Swift系统视频学习

2020-09-07  本文已影响0人  howhyone

1、
swift5.1基础语法:https://docs.swift.org/swift-book/LanguageGuide/TheBasics.html
swift5大概语法:https://www.cnblogs.com/1-434/p/10512719.html
源码地址:链接:https://pan.baidu.com/s/1Nxy3uY32JdyxaMXsKlRyhQ 密码:csua

import UIKit

let hasLogin = true
let hadHash = hasLogin.hashValue
hasLogin.description

let starCount = 12
if starCount >= 12 {
    print("hahahaha")
}

var a = 1.5
var b : Float = 2.5
var c = Float.infinity

var d : Double = 3.5

d + 0.5

d - 1.5

d * 2.0

//d� / 4

d.addProduct(1, 2)

d.advanced(by: 1.1)
d.distance(to: 16.0)

let hello = "hello"
let entity = "coolkeTang"
var helloEntity = hello + "." + entity

helloEntity += "end"
helloEntity.count

for char in helloEntity {
//    print("char is \(char)")
}

let initStr = "1233"
Int(initStr)

var message : String = "You got 3 apples"
message.hasSuffix("apples")  //是否有后缀
message.hasPrefix("You g")   //是否有前缀
message.uppercased()    //全部转大写
message.lowercased()  //全部转小写
message.capitalized  //每一个单词的首字母大写You Got 3 Apple
message.isEmpty
message.components(separatedBy: " ")
message.caseInsensitiveCompare("You got 3 apples").rawValue
message.caseInsensitiveCompare(message.uppercased()).rawValue
message.contains("apple")
message.distance(from: message.startIndex, to: message.endIndex)
message.lengthOfBytes(using: .utf8) //获得字符串在指定编码模式下的字节长度
message.range(of: "got")?.lowerBound
message.range(of: "got")?.upperBound
var shanghai = "上海"
shanghai.applyingTransform(StringTransform.toLatin, reverse: false)

message.append("ahaha")
message.insert("!", at: message.endIndex)
message.insert(contentsOf: "Hi", at: message.startIndex)

let index = message.index(message.startIndex, offsetBy: 3)
let startIndexZ = message.index(message.startIndex, offsetBy: 14)
let endIndexZ = message.index(message.endIndex, offsetBy: -17)
//let range = startIndexZ ..< endIndexZ
//print(message[range])
//message.replaceSubrange(range, with: "stars")
message = "I have 5 starts and you have 5 stars too";
message.replacingOccurrences(of: "stars", with: "apples")

let http500Error = (500, "Internal server error")
let (stateCode, stateMessage) = http500Error
//statecod
stateMessage


let tooBig : UInt8 = UInt8.max

//let onThousand: UInt8 = 1000

let stringArr = Array<String>()
let floatArr = [Float]()
var intArr = [1,2,3,4,5]
intArr.first
intArr.last
intArr.count
intArr.isEmpty
intArr.contains(3)
intArr.max()
intArr.min()
intArr.reverse()
intArr += [8,4,29]
intArr.append(100)
intArr.swapAt(2, 3)
//print("intArr is\(intArr)")
intArr[2...4] = [7,8]   //将intArr[2],intArr[3],intArr[4] 替换为7,8,8
//print("chanage intArr is \(intArr)")
intArr.insert(20, at: 4)
intArr.sort()
intArr.sort(by: {$0 > $1})
//print("chanage intArr is \(intArr)")

//print("chanage1 intArr is \(intArr)")

intArr.dropFirst()   //返回一个删除第一个元素后的 新数组
//print("chanage2 intArr is \(intArr)")

intArr
intArr.popLast()   //删除数组的最后一个元素,返回删除的最后一个元素
//print("chanage2 intArr is \(intArr)")
intArr.remove(at: 1)   //删除指定角标额元素并返回删除的元素
//print("chanage3 intArr is \(intArr)")

intArr


var numberArr1 = [1,2,3,4]
var numberArr2 = [5,6,7,8]
var numberArr = [numberArr1,numberArr1]

var newArr = Array<Array<Int>>()
newArr.append(numberArr1)
newArr.append(numberArr2)

for subArr in newArr {
    for item in subArr {
//        print(item)
    }
}


var StringArr1 = [ "a" , "b" , "c" ]
for stringItem in StringArr1 {
//    print(stringItem)
}

for i in 0 ..< StringArr1.count {
//    print(StringArr1[i])
}

for (index, value) in StringArr1.enumerated()
{
//    print("\(index):\(value)")
}

var airportDic : Dictionary<String,String> = ["DUB":"Dublin","TYO":"Tokyo"];

var firstStudent = ["Name":"Peter","Age":"12"];

var secondStudent : Dictionary<String,Any> = ["Name": "Peter", "Age": 16];

secondStudent["Name"]
secondStudent["Name"] = "Jon";
//print(secondStudent)
//secondStudent.count
secondStudent.description
secondStudent.isEmpty
secondStudent.updateValue(20, forKey: "Age")
print(secondStudent)
secondStudent.popFirst()
print(secondStudent)
secondStudent.removeValue(forKey: "Age")
secondStudent.isEmpty
print(secondStudent)
airportDic.removeAll()

firstStudent.first?.key
firstStudent.first?.value
firstStudent.reversed()

for key in firstStudent.keys {
    print(firstStudent[key] ?? 1)
}
for value in firstStudent.values {
    print(value)
}
for (key, value) in firstStudent {
    print("key = \(key),value = \(value)")
}

var dicpts : Dictionary<String,Any> = ["i":"yi","d":"asdf","dd":"were","gdafds":"gadf"]
var keyA = dicpts.keys.sorted()

for key in keyA {
    print(dicpts[key] ?? "wu")
}

**一元二元三元**
var a = 1
let b = -a
let x = false
let y = !x
//a++ 已经废弃
a += 1
a -= 1
a *= 2
a /= 2
9 % 4
//8 % 2.5  浮点型不能用于 求余运算符
8.truncatingRemainder(dividingBy:2.5)

"hello" + "world"  // 拼接字符串
[1,2] + [3,4]    //拼接数组

**位运算符**
位或 ( | ) 有1为1,全0为0
位与( & ) 有0为0,全0为1
位异或 ( ^ )相同为0,不同为1
et binaryBits : UInt8 = 0b00101011
let invertedBinaryBits = ~binaryBits
let firstBits : UInt8 = 0b11111100
let lastBits :UInt8 = 0b00111111
let resultBits = firstBits & lastBits
let outputBits = firstBits ^ lastBits

let shiftBits : UInt8 = 4
shiftBits << 2  //通过左移运算符,将整数的二进制数值左移两位,使整数的值放大到4倍
[swift位运算符详细介绍](https://www.yiibai.com/swift/swift_bitwise_operators.html)
[进制转换](https://blog.csdn.net/Limit_Fly/article/details/90708281)

**比较运算符和区间运算符**
1 == 1
2 != 1

for i in 1 ... 5 {
    print(i)
}
for j in 1 ..< 5{
    print(j)
}

let isMale = true
let isFemale = false

isMale && isFemale
isMale || isFemale
(isMale && isFemale) && (isMale || isFemale)
**循环语句**
for _ in 1 ..< 5 {
    print("You get a star.")
}

for i in 1 ... 5 {
    print(i)
}

for itemArr in [1,3,5] {
    print(itemArr)
}

let url = "www.mob.com"
for charS in url {
    print(charS)
}
**for循环求最小值**
let cardNumber = [
    "Clubs":[22,32,54,83,100],
    "Hearts":[67,101,23,-1],
    "Square":[122,34,1]
]
var min = Int.max
for (_,valueArr) in cardNumber {
    for (item) in valueArr {
        if min > item {
            min = item
        }
    }
}
print(min)
**switch-case**
let time = 20
var message = ""
switch time {
case 7:
    message = "It is time to get up"
case 8,12,18:
    message = "It is time to eating"
case let x where x > 18 && x < 24:
    message = "Happy time"
case 1 ... 6:
    message = "It is time for rest";
default:
    message = "you had dead"
}

**contine ,break, fallthrough  **
var sum = 0
for i in 1 ... 4 {
    if i == 2 {
        continue
    }
    sum += i
}
sum

let time = 6
var description = "It is"
switch time {
case 2,3,6,10:
    description += " \(time) o'clock"    //"It is 6 o'clock"
    fallthrough
case 100:
    description += " hahah"             //"It is 6 o'clock hahah"
default:
    description += "."
}
**if 和 if let 语句**
var i = 2
while i  < 6 {
    i += 1
}

var j = 2

repeat{
    j += 1
}while j < 6
j
var optionalName : String? = "world"
var greeting = "Hello"
if let name = optionalName {
    print(greeting + name)
}

**创建方法**
func sayHelloSwift()
{
    print("Hello, Swift")
}

sayHelloSwift()

func sayHelloSwift(to: String)
{
    print("Hello, \(to)")
}

sayHelloSwift(to: "Xcode")

func saySomething() -> String
{
    return "Hello, badGirl"
}
let sayWhat = saySomething()

func sayGreeting(to: String) -> String
{
    return "haah"
}
let sayGreetingStr = sayGreeting(to: "xcode")

func getDistance(startPoint point1: CGPoint, endPoint point2: CGPoint) -> CGFloat
{
    let xDistance = point1.x - point2.x
    let yDistance = point1.y - point2.y
    return xDistance * yDistance
}

let p1 = CGPoint(x:0,y:0)
let p2 = CGPoint(x: 100, y: 100)
let xy = getDistance(startPoint: p1, endPoint: p2)

func getDistance(point1: CGPoint, point2: CGPoint) -> CGFloat
{
    let xDistance = point1.x - point2.x
    let yDistance = point1.y - point2.y
    return sqrt(xDistance * xDistance + yDistance * yDistance)
}
let xyDistance = getDistance(startPoint: p1, endPoint: p2)
**无限参数**
注意:
一个函数最多只能拥有一个可变参数。
func getAverage(numbers: Double ...) -> Double
{
    if numbers.count == 0 {
        return 0.0
    }
    var total: Double = 0.0
    for number in numbers {
        total += number
    }
    return total / Double(numbers.count)
}

print(getAverage())
getAverage(numbers: 1,2,3,4)

**输入输出参数**
作为输入输出参数进行修改。
输入输出参数:定义一个输入输出参数时,在参数定义前加 inout 关键字。一个输入输出参数有传入函数的值,这个值被函数修改,然后被传出函数,替换原来的值。
你只能传递变量给输入输出参数。你不能传入常量或者字面量,因为这些量是不能被修改的。当传入的参数作为输入输出参数时,需要在参数名前加 & 符,表示这个值可以被函数修改。

func swap(a: inout Double, b: inout Double)
{
    let temp = a
    a = b
    b = temp
    
}
var myScore = 6.5
var yourScore = 9.0
swap(&myScore, &yourScore)  //调用函数,并在变量名称之前放置一个连字符(&),表示可以
**方法函数默认参数值**
默认参数传值了用传的值, 默认参数未传值是用默认值
func getDistance(startPoint: CGPoint,endPoint: CGPoint = CGPoint(x: 0, y: 0)) -> CGFloat
{
    let xDistance = startPoint.x - endPoint.x
    let yDistance = startPoint.y - endPoint.y
    
    return sqrt(xDistance * xDistance + yDistance * yDistance)
}
let p1 = CGPoint(x: 100, y: 100)
let p2 = CGPoint(x: 200, y: 200)

getDistance(startPoint: p1, endPoint: p2)
getDistance(startPoint: p2)
****
func getTotal(number1: Int, number2: Int) -> Int
{
    return number1 + number2
}

func getBigger(num1: Int, num2: Int) -> Int
{
    return num1 > num2 ?num1 : num2
}

func getMathResult(function:(Int,Int) -> Int, a:Int, b:Int) -> Int
{
    return function(a,b)
}

getMathResult(function: getTotal(number1:number2:), a: 10, b: 20);

getMathResult(function: getBigger(num1:num2:), a: 20, b: 10)

**解析函数类型**
func getTotal(number1: Int, number2: Int) -> Int
{
    return number1 + number2
}
getTotal(number1: 1, number2: 1)

let newFunction:(Int,Int) -> Int = getTotal(number1:number2:)

newFunction(1,1)

let otherFunction = getTotal(number1: 1, number2: 1)

func printHelloWift()
{
    print("Hello Swift")
}
let anotherGreeting: () -> () = printHelloWift  //无参数无返回值的函数用()-> ()表示

anotherGreeting()  

**使用函数类型作为返回值**
func stepForword(input : Int) -> Int
{
    return input + 1
}

func stepBackward(input : Int) -> Int
{
    return input - 1
}

func chooseStepFunction(isBack : Bool) -> (Int) -> (Int)
{
    isBack ? stepBackward(input:) : stepBackward(input:)
}

let move = chooseStepFunction(isBack: false)

move(0)
**多个返回值**
func caculate(string: String) -> (vowels: Int, consonats: Int, others: Int)
{
    var vowels = 0
    var consonats = 0
    var others = 0
    for char in string {
        
        switch String(char).lowercased() {
        case "a", "e", "i", "0", "u":
            vowels += 1
        case "b", "c", "d", "f","g", "h", "j", "k", "l","n","p","q","r","s","t","v","w","x","y","z":
            consonats += 1
        default:
            others += 1;
        }
    }
    return(vowels,consonats,others)
}

caculate(string: "Hello, Swift!")
**方法里面嵌套方法**
func chooseFunctino(isteap: Bool) -> (Int)
{
    func stepForword(forword: Int) -> (Int)
    {
        return forword + 1
    }
    func stepAfter(after: Int) -> (Int)
    {
        return after - 1
    }
    
    return isteap ? stepAfter(after: 1) : stepForword(forword: 2)
}

chooseFunctino(isteap: 1 > 2)

**函数的递归思想**
func recursion(n:Int) -> Int
{
    if n <= 1 {
        return 1
    }else{
        return recursion(n: n-1) + recursion(n: n-2)
    }
}

recursion(n: 8)
**swift常用的函数**
abs(-32)   //绝对值
assert(true)
max(1, 2)
max(1, 2, 3, 4)
min(1, 2)
print("Hello","world")
debugPrint("Hello","world")
print("I", "have", 5, "starts",separator: " ... ", terminator: "?\n")

let zoroes = repeatElement("start", count: 5) //重复元素生成数组
for x in zoroes
{
    print(x)
}

var a = "siwft"
var b = "xcode"
swap(&a, &b)
a
b
type(of: "aa")  //获取参数的类型
type(of: 1)
type(of: 1.5)

for i in (1 ... 10).filter({$0 % 3 == 0}) {  //过滤函数,身下3的整数
    print(i)
}

for i in (1 ... 4).map({$0 * 3}) {        // mapi对参数做闭包处理,都乘以3
    print(i)
}

let result = (1 ... 4).reduce(1, {$0 + $1})  // 1 和 数组元素累加的值
print(result)
**枚举,遍历枚举**
enum Orientaion
{
    case North
    case South
    case East
    case West
}
Orientaion.North

enum Fruit
{
    case Apple, Banana, Orange, Peach, Watermelon
}

var myFavorite = Fruit.Apple
myFavorite = .Orange
var planet = Orientaion.East

switch  planet{
case .East:
    print("haahah")
default:
    print("where is ");
}

enum ASCIIChar : Character
{
    case Tab = "\t"
    case LineFeed = "\n"
    case CarriageRetur = "\r"
}

print(ASCIIChar.Tab)

**给枚举类型添加方法**
enum Language: Int
{
    case Swift = 2
    case ObjectiveC
    case Unknow
    
    func description()
    {
        if self == .Swift {
            print("Coding in swift")
        }else if self == .ObjectiveC {
            print("Coding in ObjectiveC")
        }else if self == .Unknow{
            print("Coding in Unknow")
        }
    }
}
let swift = Language.Swift
swift.description()
swift.rawValue
Language.ObjectiveC.rawValue

**结构体下标**
struct Animal
{
    var name: String = ""
    var age: Int = 0
    func say()
    {
        print("I am \(name).")
    }
}

var animal = Animal(name: "Tiger", age: 2)
animal.say()

var animal2 = animal
animal2.name = "Bird"
print(animal2)
print(animal)

struct MySubscript
{
    var num: Int
    subscript(n: Int) -> Int  // 使用subscript关键字给结构体添加一个下标操作,用来返回当前属性的值的指定倍数,使用下标可以访问集合或序列成员元素的快捷方式
    {
        return num * n
    }
}
let subscr = MySubscript(num: 5)  //对结构体初始化 并赋值
subscr[2]               //最后对结构体对象使用下标操作
**类的初始化和调用**
class Person
{
    var name: String
    var age: Int
    
    init() {
        self.name = ""
        self.age = 0
    }
    
    convenience init(name: String!, age: Int)
    {
        
        self.init()
        self.name = name
        self.age = age
    }
    
    func say() {
        print("Hi, I am \(name), and \(age) years old.")
    }
}

let person = Person()
person.name = "Jerry"
person.age = 35
person.say()

let secondPerson = Person(name: "bill", age: 32)
secondPerson.say()
**类的引用**
class Animal
{
    var name: String
    var age: Int
    
    init(animalName: String, age: Int) {
        self.name = animalName
        self.age = age
    }
    func say() {
        print("Hi, I am \(name)")
    }
}

let animal = Animal(animalName: "Will", age: 20)
let animal2 = animal
animal2.name = "Tom"
animal.say()   //    Hi, I am Tom
animal2.say()  //   Hi, I am Tom
//animal和animal2对象 是一致的,改变一个,另一个也会改变
**类和结构体的对比**
struct Animal
{
    var name: String
    var age: Int
}

let tiger = Animal(name: "Tiger", age: 2)
var lion = tiger
lion.name = "lion"
print("tiger.name \(tiger.name),lion.name \(lion.name)")
打印:tiger.name Tiger,lion.name lion

class Person
{
    var name : String
    var age: Int
    init() {
        self.name = "Jerry"
        self.age = 0
    }
}
let person1 = Person()
let person2 = person1
preson2.name = "Tom"
print("person1.name \(person1.name) person2.name\(person2.name)")
打印:person1.name Tom person2.nameTom

总结:修改结构体参数用var修饰,赋值是深拷贝的 方式,修改一个对象的值,其他结构体 对象不影响,类的对象可以用let修饰,赋值是浅拷贝,修改一个其他参详也会变
**类的set和get方法**
class Player
{
    var name : String = "Tom"
    var level : Int = 3
    var score: Double  //给score参数手动设置get和set方法
    {
        get
        {
            name = "Lam"
           
            return Double(level) * 2.0
        }
        set(newScore)
        {
            level = Int(newScore)/2
            name = "Jim"
        }
    }
}

let player = Player()
player.score
print("name \(player.name),score \(player.score)")
打印结果:name Lam,score 6.0
player.score = 8
print("name \(player.name),score \(player.score)")
打印结果:name Jim,score 8.0
player.level
**类的析构函数**
class Animal1 {
    var name: String
    var age: Int
    init(name: String,age: Int) {
        self.name = "Tom"
        self.age = 2
    }
    
    func say() {
        print("I am \(name)")
    }
    deinit {
            print("I`m deinited")
    }
}
 let animal: Animal1? = Animal1(name: "Jerry", age: 33)
类的析构函数:当引用计数为0 时自动调用析构函数deinit,通常在析构函数中释放一些资源(如移除通知等操作)
**类的下标**
下标是访问集合、列表、序列中的元素的快捷访问方式,结构体、枚举和类都可以定义下标
class Person1
{
    var name: String = "Rocky"
    var age: Int = 20
    var height: Double = 130
    
    subscript(index: Int) -> AnyObject
    {
        switch index
        {
            case 0:
                return name as AnyObject
            case 1:
                return age as AnyObject
            case 2:
                return height as AnyObject
            default:
                return name as AnyObject
        }
    } 
}
 let person: Person1 = Person1()
        let age = person[1]
        let height = person[2]
        let name = person[4]

**类的静态方法**
静态方法相当于OC的类方法,用类名调用
class MathTool
{
    func alert()  {
        print("Caculating....")
    }
    func sum(num1: Int,num2: Int) -> Int {
        alert()
        return num1 + num2
    }
    class func multiply(num1: Int, num2: Int) -> Int{
        return num2 * num1
    }
}

let mathTool = MathTool()
mathTool.alert()
mathTool.sum(num1: 1, num2: 2)
MathTool.multiply(num1: 3, num2: 4)

**讲一个类的实例座位另一个类的属性**
懒加载:使用 lazy 修饰属性时,必须声明属性是变量。而且我们需要显示的指定属性的类型。对该属性进行一个赋值语句用来首次访问时使用。
class Animal
{
    var name: String = "Lovely Dog"
    var age = 1

}

class Person
{
    var name = "Jerry"
    var age: Int = 33
    lazy var pet: Animal = Animal()
    
}

let person = Person()
person.name
person.age
person.pet.name
person.pet.age
**类的继承和重写**
class Animal
{
 
    func say()  {
        print("I am animal....")
    }
}

class Dog: Animal
{
    var name: String
    
    init(name: String) {
        self.name = name
    }
    override func say() {
        super.say()
        print("I am a dog my name is \(name)")
    }
}

var dog = Dog(name: "Tom")
dog.say()

**父类在实例转化中的应用**
class Animal
{
    var name: String
    init(name: String) {
        self.name = name
    }
}

class Dog: Animal
{
    var master: String
    init(name: String,master: String){
        self.master = master
        super.init(name: name)
    }
}
let creatures:[Animal] = [
                            Dog(name: "Nono", master: "Tom"),
                            Dog(name: "Bala", master: "Jim"),
                            Dog(name: "Baby", master: "Yam")
                         ]
for object in creatures {
    let dog = object as! Dog  
    print("name \(dog.name),master is \(dog.master)")
}
// as! 向下强制类型转换
**使用is语句检查实例的类型**
class Animal
{
    var name: String
    init(name: String) {
        self.name = name
    }
}

class Dog: Animal
{
    var master: String
    init(master: String, name: String){
        self.master = master
        super.init(name: name)
    }
}

class Bird: Animal
{
    var food: String
    init(food: String,name: String){
        self.food = food
        super.init(name: name)
    }
}

let creatures: [Animal] = [
    Dog(master: "Tom", name: "laha"),
    Bird(food: "Jim", name: "jiza"),
    Dog(master: "Zed", name: "wangwang")
]

var dogCount = 0
var birdCount = 0


for object in creatures {
    if object is Dog {
        dogCount += 1
    }else if object is Bird{
        birdCount += 1
    }
}
print("dogcount is \(dogCount),birdcount is \(birdCount)")

for object in creatures {
    if let dog = object as? Dog {
        print("name is \(dog.name), master is \(dog.master)")
    }else if let bird = object as? Bird{
        print("name is \(bird.name), food is \(bird.food)")
    }
}
**Any 任意类型**
var anything = [Any]()
anything.append(8)
anything.append(3.1415)
anything.append("hello")
anything.append((3.0,4.0))
anything
for item in anything {
    switch item {
    case let someInt as Int:
        print(someInt)
    case let someDouble as Double:
        print(someDouble)
    case let someString as String:
        print(someString)
    case let (x,y) as(Double,Double):
        print(x,y)
    default:
        print("xixi")
    }
}
/**as的用法
1, 子类向父类转换,向上
2,强制类型转换
3,switch语句是类型判断
 **/
**使用extension对方法进行扩展**
extension Int
{
    var double:Int{
        return self * 2
    }
    var triple:Int{
        return self * 3
    }
    var fourfold: Int{
        return self * 4
    }
    var half: Double{
        return Double(self) / 2
    }

}
2.double     4
2.triple        6
2.fourfold    8
2.half           1
//扩展详解:[https://www.jianshu.com/p/0c963bc2194c](https://www.jianshu.com/p/0c963bc2194c)

**类的协议protocol**
protocol Walking
{
    func walking()
}
protocol Eating {
    func eating()
}
protocol Fighting:Walking{ // Fighting协议遵守Walking协议,用:冒号隔开
    func fight()
}

class Animal: Fighting,Eating
{
    func fight() {
        print("Fighting ......")
    }
    
    func eating() {
        print("eating  ........")
    }
    
    func walking() {
        print("walking .......")
    }
    
    func say(){
        print("say ......")
    }
}

let animal = Animal()
animal.fight()    Fighting ......
animal.eating()    eating  ........
animal.walking()   walking .......
animal.say()          say ......

extension Animal
{
    var weight: Double
    {
        get{
            return 15.0
        }
    }
    
    func getWeight() -> Double {
        return 45.0
    }
    
}

let secondAnimal = Animal()
secondAnimal.weight    15.0
secondAnimal.getWeight()     45.0
**?和!的用法**
var password: Optional<Any>
var password1:NSString?
print(password1?.length ?? 0)
var password3: NSString?


var password2:NSString?
print(password2?.length ?? 0 )

var password4: String! = "123456"
print(password4!.count)
class Pet
{
    var name: String?
        
}

class Person
{
    var name: String?
    var pet: Pet?
}

let person = Person()
person.name?.count   //?表示判断person.name的值,当person.name的值为空时,不在访问count参数
person.pet = Pet()
person.pet?.name
[参考2](https://www.jianshu.com/p/eacd24f0adaf)

**泛型函数**
func appendToGenericArray<T>(array1:[T], array2:inout [T])  //inout关键字修饰的字被修改会影响全局,影响函数外的值
{
    for item in array1 {
        array2.append(item)
    }
}
// 在方法名后面用尖括号包含大写字母T,表示泛型函数,参数的类型也用T表示
var array = [1,2,3]
appendToGenericArray(array1: [6,5,4], array2: &array)

var arrayStr = ["2","4"]
var toArrayStr = ["hahah","lalal"]

appendToGenericArray(array1: arrayStr, array2: &toArrayStr)

func appendToGeneralString<T>(string:T,toString:T)
{
    print(string)

}
appendToGeneralString(string: "ss", toString: "ssaa")  //ss
appendToGeneralString(string: 1, toString: 3)               //  1
appendToGeneralString(string: arrayStr, toString: toArrayStr)  // ["2", "4"]
appendToGeneralString(string: array, toString: array)       // [1, 2, 3, 6, 5, 4]

**do-try-catch**
enum ErrorType: Error
    {
        case invalidProduct
        case insufficientCoins(coinsNeeded: Int)
        case outOfStock
    }

    struct Product
    {
        var price: Int
        var count: Int
    }



    class Shop
    {
         var totalCoins = 10
        var products = [
            "Pudding": Product(price: 12, count: 7),
            "Dount": Product(price: 10, count: 0),
            "Cheesepuff":Product(price: 7, count: 11)
        ]
        func sell(productName: String) throws {
            guard let product = products[productName] else{
                throw ErrorType.invalidProduct
            }
            guard product.count > 0 else {
                throw ErrorType.outOfStock
            }
            guard totalCoins > product.price  else {
                throw ErrorType.insufficientCoins(coinsNeeded: product.price - totalCoins)
            }
            
        }
    }

**析构函数**
class MathTool
{
    var name: String
    init(name: String) {
        self.name = name
    }
    deinit {
        print("----------- name")
    }
}

var person:MathTool? = MathTool(name: "zhangsan")
var person1 = person
person1?.name = "lisi"
print("person.name \(person?.name ?? "2"),person1.name \(person1?.name ?? "1")")
var person2 = person
person1 = nil
person = nil
person2 = nil
打印结果:person.name lisi,person1.name lisi        ----------- name

**相互循环引用和weak 弱引用修饰符**
class People
{
    var name: String
    var pet:Pet?
    
    init(name: String) {
        self.name = name
    }
    deinit {
        print("----------- name")
    }
}

class Pet
{
    var name: String
    weak var master: People?    //添加weak修饰符,不添加会一直循环引用,dog和master对象无法释放
    init(name: String) {
        self.name = name
        
    }
    
    deinit {
            print("Pet is deinitialized.")
    }
}

var master:People?
var dog:Pet?
master = People(name: "zhangsan")
dog = Pet(name: "wangwang")
master?.pet = dog
dog?.master = master

master = nil
dog = nil
**懒加载**
class Demo
{
    var url: NSString
    lazy var completeURL: NSString = {
        if self.url.hasPrefix("http://") {
            return self.url
        }else{
            return "http://\(self.url)" as NSString
        }
        
    }()  //记得加赠()括号
    
    init(url:NSString) {
        self.url = url
    }
    
}

let demo = Demo(url: "www.coolketang.com")
demo   //url有值,completeURL为nil
demo.url
demo.completeURL
demo //url有值,completeURL有值
**范围Range**
let closeRange: ClosedRange = 1...3
let intArray = [1,2,3,4,5,6,7]
intArray[closeRange]

let halfOpenRange = 1..<3
intArray[halfOpenRange]

var myUrl = "coolketang.com"
let startIndex = myUrl.index(myUrl.startIndex, offsetBy: 0)
let endIndex = myUrl.index(myUrl.endIndex, offsetBy: -10)
let myRange = startIndex ..< endIndex

let range = NSRange.init(location: 1, length: 2)
intArray[Range.init(range)!]

let myWebsite = myUrl as NSString
myWebsite.substring(with: NSRange.init(location: 1, length: 2))//截取部分字符串,substring是NSString类的方法,String强制转换为NSString

**CGPoint 和仿射变换CGAffineTransform**
let zeroPoint = CGPoint.zero

let x = zeroPoint.x
let y = zeroPoint.y

zeroPoint.debugDescription
zeroPoint.equalTo(CGPoint(x: 0, y: 0))

var secondPoint = CGPoint(x: 10, y: 10)
let transform:CGAffineTransform = CGAffineTransform.identity
let moveTranslation = transform.translatedBy(x: 10, y: 10) // 将仿射变换对象在水平和垂直方向各平移10点
let thirdPoint = secondPoint.applying(moveTranslation)  // 将平移后的点对象赋值给thirdPoint
let rotateTransform = moveTranslation.rotated(by: 90 * 3.1415/180.0) //对仿射变换对象进行旋转90度,旋转角度d为弧度方式
let fouthPoint = thirdPoint.applying(rotateTransform)

**CGPoint**
let zeroSize = CGSize.zero
let size = CGSize(width: 20, height: 20)
size.debugDescription

let affineTransform: CGAffineTransform = CGAffineTransform.identity
let translation = affineTransform.translatedBy(x: 10, y: 10)
let tanslationSize = size.applying(affineTransform)
let scale1 = translation.scaledBy(x: 2.0, y: 3.0)
let scaleSize = size.applying(scale1)

let fifthSize = NSCoder.cgSize(for: "{200,100}")  //使用系统接口可以使用字符串
**CGRect**
let rect = CGRect(x: 0, y: 0, width: 100, height: 100)
rect.debugDescription

let originPoint = CGPoint.zero
let size1 = CGSize(width: 100, height: 100)
let secondRect = CGRect(origin: originPoint, size: size1)
secondRect.origin.x
secondRect.origin.y
secondRect.size.width
secondRect.size.height
secondRect.width
secondRect.height
secondRect.minX
secondRect.maxX
secondRect.minY
secondRect.maxY

secondRect.contains(CGPoint(x: 10, y: 10))                        //是否包含该点
secondRect.contains(CGRect(x: 10, y: 10, width: 10, height: 10)) //是否包含该区域
secondRect.equalTo(rect)
secondRect.insetBy(dx: 10, dy: 10)   //截取secondRect区域的和边界相距10 的区域
secondRect.intersection(CGRect(x: 10, y: 10, width: 10, height: 200))  //获取 和另一个区域相交的部分
secondRect.intersects(CGRect(origin: originPoint, size: size1))   //判断两个区域是否相交
secondRect.offsetBy(dx: 10, dy: 10)  //获取 区间水平和垂直各偏移10点之后的区域
secondRect.union(CGRect(x: 30, y: 30, width: 300, height: 300)) // 获取两个区域合并后的区域

NSCoder.cgRect(for: "{{0,0},{100,100}}")   //和点对象,尺寸对象相同,同样可以将一个格式化的字符串,转换为区域对象
**字符串**
let string = NSString(string: "meet")
let floatString = NSString(format: "%f", 25.0)
var secondString = string.appending("coolketang.")
secondString.capitalized
secondString.caseInsensitiveCompare("test").rawValue  //-1表示当两个字符串进行排序时,当前字符串位于进行比较的字符串前方 ,0表示两个字符串相同,1表示在比较的字符串后面,
secondString.commonPrefix(with: "meet swift") // 获取两个字符串相同的前缀
secondString.contains("coolketang")
secondString.data(using: .utf8) //返回该字符串urf8格式的数据
secondString.hasPrefix("meet")
secondString.hasSuffix("coolketang.") // 后缀是否包含这个
secondString.insert(".", at: secondString.endIndex) // 插入字符串到指定的位置
secondString.lengthOfBytes(using: .utf8)  // 获取字符串在指定编码格式下的长度
secondString.count                      // 获取字符串中字符的数量
secondString.lowercased()
secondString.uppercased()
secondString.range(of: "meet")?.lowerBound  //获得meet字符串在secondString中的起始和终点位置
secondString.range(of: "meet")?.upperBound
secondString.removeSubrange(secondString.range(of: "meet")!) //删除指定区间的字符串
secondString.replacingOccurrences(of: "cool", with: "swift") //将字符串存在的字符串替换成后面的字符串,不存在就不替换
secondString[secondString.index(secondString.startIndex, offsetBy: 2)]  // 从指定的位置开始,往后偏移的字符,
**Date和DateFormatter**
var date = Date()
date.addTimeInterval(60*60)
let secondDate = date.addingTimeInterval(60*60)
secondDate.compare(date.addingTimeInterval(60*60)).rawValue
secondDate.description
secondDate.debugDescription
secondDate.timeIntervalSince(date)  //截止到该时间的间隔
secondDate.timeIntervalSince1970
secondDate.timeIntervalSinceNow

let dateFormatter = DateFormatter()  // 初始化一个日期格式化的对象
dateFormatter.locale = Locale.current //设置日期格式化d对象的本地属性
dateFormatter.dateStyle = DateFormatter.Style.full // 设置包含年月日星期的日期格式
dateFormatter.string(from: date)   //查看该格式的日期 
dateFormatter.dateStyle = DateFormatter.Style.long   
dateFormatter.string(from: date)
dateFormatter.dateStyle = DateFormatter.Style.medium  // Sep 17, 2020
dateFormatter.string(from: date)
dateFormatter.dateStyle = DateFormatter.Style.short   // 9/17/20
dateFormatter.string(from: date)
dateFormatter.dateFormat = "yyyy-MM-dd hh:mm:ss"  //12小时制 2020-09-17 07:10:22
dateFormatter.string(from: date)
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"  //24小时制  2020-09-17 19:10:44
dateFormatter.string(from: date)
dateFormatter.dateFormat = "yyyy-mm-dd"
dateFormatter.string(from: date)                //2020-02-19
dateFormatter.dateFormat = "yyyy-M-dd"
dateFormatter.string(from: date)                //  2020-2-19
let dateString = "2017-06-02 19:15:59"
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let newDate = dateFormatter.date(from: dateString)
(newDate?.timeIntervalSinceReferenceDate)! > date.timeIntervalSinceReferenceDate
**日期组件DateComponent**
let date = Date()
let currentCalendar = Calendar.current
let dateComponents = currentCalendar.dateComponents([Calendar.Component.era,Calendar.Component.year,Calendar.Component.month,Calendar.Component.day,Calendar.Component.hour,Calendar.Component.second,Calendar.Component.minute], from: date)   // 初始化date的日期组件
dateComponents.era  // 1
dateComponents.year   //2020

var component = DateComponents()
component.year = 2020
component.month = 09
component.day = 03
let dateComponent = currentCalendar.date(from: component)  // 日期由日期组件 拼成显示
**Calendar和 时区Timezone**
var calendar: Calendar = Calendar.current
calendar.locale = Locale(identifier: "zh_CN")
calendar.timeZone = TimeZone(abbreviation: "EST")!  //EST 美东时区的缩写
//calendar.timeZone = TimeZone(secondsFromGMT: +28800)!  //距格林时间28800s的时区(中国时区)60*60*8 8个小时

calendar.firstWeekday = 2       //设置日历第一个工作日为2
calendar.minimumDaysInFirstWeek = 3; //设置第一周最小的天数为3
calendar.locale
calendar.timeZone
let date = Date()

calendar.isDateInToday(date)
calendar.isDateInTomorrow(date)
calendar.isDateInYesterday(date)

**NSTimer的使用**
class ViewController: UIViewController {

    var appleCount = 0
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
//        let timer = Timer(timeInterval: 1.0, repeats: false) { (timer) in
//            print("hahhahah")
//        }
//        timer.fire()
        
//        Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { (scheduledtTimer) in
//            print("scheduleTimer \(scheduledtTimer)")
//        }
        
        Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(ViewController.timerAction(_:)), userInfo: "an apple", repeats: true)
    }
    @objc func timerAction(_ timer:Timer)
    {
        if self.appleCount == 3 {
            timer.invalidate()
            return
        }
        let parameter = timer.userInfo as! String
        print("I am eating \(parameter)")
        self.appleCount += 1
        
    }

}

**URL的使用**
let url = URL(string: "http://www.coolketang.com")
url?.absoluteString   //获取url的字符串格式

var secondUrl = url?.appendingPathComponent("demo/login/")
//secondUrl?.deleteLastPathComponent()  //获取当前目录的上一级目录
secondUrl?.host             //域名
secondUrl?.lastPathComponent  //获取url的最后一个目录

let thirdUrl = URL(string: "http://www.coolketang.com:8080/login.action?username=jerry")
thirdUrl?.port  // 获得网址对象的端口号
thirdUrl?.query  // 获取网址对象的查询参数
thirdUrl?.scheme  // 获得网址对象的scheme

let targetPath:String = NSHomeDirectory() + "/Documents/music.png"
let fileUrl = URL(string: targetPath)
fileUrl?.pathComponents
fileUrl?.pathExtension //扩展名 png
**多线程**


**UIScreen获取屏幕信息**
UIScreen.main.availableModes.description
UIScreen.screens.count  //屏幕数量
UIScreen.main.bounds  //属性 屏幕的bounds
UIScreen.main.nativeBounds  //属性 物理屏幕的像素
UIScreen.main.nativeScale  //属性 设备物理屏幕的比例因子
UIScreen.main.brightness  //属性 屏幕亮度等级
UIScreen.main.coordinateSpace.bounds   //属性 当前屏幕的坐标空间

UIScreen.main.currentMode?.size

**UIColor**
UIColor.orange
UIColor.clear

let color = UIColor(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
let secondColor = UIColor(white: 1.0, alpha: 0.5)
let thirdColor = UIColor(hue: 0.3, saturation: 0.75, brightness: 0.50, alpha: 1.00) //获取指定色相、饱和度、亮度、不透明度颜色模式下的颜色

let image = UIImage()
let thirdColor = UIColor(patternImage: image)  //将图片转成color,平铺在界面
color.cgColor
color.withAlphaComponent(0.5)
let view = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
view.backgroundColor = color
**swift语言的两种单例模式**
//      静态常量单例
final class SingleClass:NSObject //final可以防止类被继承,也可以防止类被重写方法,属性以及下标subscript,final不能用于结构体和枚举
{
    static let shared = SingleClass()  //static 定义一个静态常量,静态常量在实例调用结束后不会消失,并且保留原有值,即内存空间不会被释放,下次调用还能读取原有值
    private override init() {     //单例的构造器必须是private的,以防止其他对象也能创建出该单例类的实例
        
    }
    
    func say()
    {
        print("Hello,")
    }
}

SingleClass.shared.say()
//      静态变量单例
final class SecondSingleClass: NSObject
{
    static var secondSingleClass: SecondSingleClass   //使用静态变量的方式创建单例
    {
        struct StaticS                  //借助结构体来存储类型变量,并使用let修饰符来保证线程的安全
        {
            static let instanceS: SecondSingleClass  = SecondSingleClass()
        }
        return StaticS.instanceS
    }
    func say()
    {
        print("Hello,ahahahha")
    }
    
}

SecondSingleClass.secondSingleClass.say()

**swift中的三种消息传递模式**
class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        let width = Int(self.view.frame.size.width - 40)
        let greetButton = UIButton(frame: CGRect(x: 20, y: 100, width: width, height: 40))
        greetButton.setTitle("Greeting", for: .normal)
        greetButton.backgroundColor = UIColor.blue
//        greetButton.addTarget(self, action: #selector(ViewController.ganshane(_:)), for: .touchUpInside)
//        greetButton.addTarget(self, action: #selector(ganshane(_:)), for: .touchUpInside)   //本类的点击事件方法可以省略掉方法前的类名
        let buttonMethod: Selector = #selector(ganshane(_:))    //初始化选择器对象
        greetButton.addTarget(self, action: buttonMethod, for: .touchUpInside)
        
        greetButton.tag = 1
        self.view.addSubview(greetButton)
        
        let newSelector:Selector = #selector(calledByController)
//        self.perform(newSelector)   // 使用perform方法在子线程调用选择器
//        self.perform(newSelector, with: nil, afterDelay: 2.0)  //在子线程上调用选择器,传递参数为nil,并延长2秒
//        self.perform(newSelector, on: .main, with: nil, waitUntilDone: true )
        //选择在主线程中调用选择器,并等待动作的执行,
        self.performSelector(inBackground: newSelector, with: nil) //选择在后台线程中h运行selector方法
    }
    
    @objc func ganshane(_ button:UIButton)
    {
        let tag = button.tag
        print("button touchUpInside  \(tag)")
    }
    
    @objc func calledByController()
    {
        print("perform  calledByController")
    }
    
    @objc func delayMethod()
    {
        print("delayMethod-----")
    }
}

**闭包在计时器,动画,线程中的使用**
class ViewController: UIViewController {

    var animationView: UIView!
    override func viewDidLoad() {
        super.viewDidLoad()
        Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { (timer:Timer) in
            print("Timer action .....")
        }
        
        animationView = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 40.0, height: 40.0))
        animationView.backgroundColor = .green
        self.view.addSubview(animationView)
        
        UIView.animate(withDuration: 3.0, animations: {
            self.animationView.frame = CGRect(x: 200.0, y: 0.0, width: 40.0, height: 40.0)
        }) { (Bool: Bool) in
            print("Animation done")
        }
        
        Thread.detachNewThread {                //新建一个线程
            print("Do something on a new thread")
        }
        DispatchQueue.main.async {
            print("DispatchQueue.main.async")
        }
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 2.0) {
            print("DispatchQueue.main.asyncAfter")
        }
    }
**两个对象调用 进行消息传递**
import UIKit
class CurrentView: UIView, UITextFieldDelegate {
    var textField: UITextField!
     weak var controller: ViewController?    // 定义另一个对象
    override init(frame: CGRect) {
        super.init(frame: frame)
        textField = UITextField.init(frame: self.bounds)
        textField.font = UIFont.systemFont(ofSize: 14)
        textField.textColor = .purple
        textField.layer.shadowColor = UIColor.black.cgColor
        textField.layer.shadowOffset = CGSize(width: 0.0, height: 3.0)
        textField.layer.shadowOpacity = 0.45
        textField.layer.shadowRadius = 3
        textField.backgroundColor = .lightGray
        textField.delegate = self
        self.addSubview(textField)
    }
    
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        self.controller?.checkForm()     // 引用顶一个对象的方法
        return true
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

}

import UIKit   // 另一个对象的文件
class ViewController: UIViewController,UITextFieldDelegate {
    
    var nameView : CurrentView!
    var passwordView : CurrentView!
    var submitButton : UIButton!
    override func viewDidLoad() {
        super.viewDidLoad()
        let width = Int(self.view.frame.size.width) - 40
        let height = 40
        nameView = CurrentView(frame: CGRect(x: 20, y: 80, width: width, height: height))
        nameView.backgroundColor = .green
        nameView.controller = self
        self.view.addSubview(nameView)
        
        passwordView = CurrentView(frame: CGRect(x: 20, y: 140, width: width, height: height))
        passwordView.backgroundColor = .green
        passwordView.controller = self
        self.view.addSubview(passwordView)
        
        submitButton = UIButton(frame: CGRect(x: 20, y: 240, width: width, height: height))
        submitButton.setTitle("Sumbit", for: .normal)
        submitButton.addTarget(self, action: #selector(sumbitForm(_:)), for: .touchUpInside)
        submitButton.backgroundColor = .gray
        submitButton.isEnabled = false
        self.view.addSubview(submitButton)
    }
    
    @objc func sumbitForm(_ sender: UIButton)
    {
        print("sumbit login")
    }
    @objc func checkForm()
    {
        if nameView.textField.text != "" && passwordView.textField.text != "" {
            submitButton.isEnabled = true
            submitButton.backgroundColor = .yellow
        }else{
            submitButton.isEnabled = false
            submitButton.backgroundColor = .gray
        }
    }
   
}
**swift中栈stack的使用,queue**
栈:先进后出
队列:先进先出
class Stack
{
    var stack:Array<AnyObject>
    init() {
        stack = [AnyObject]()
    }
    func isEmpth() -> Bool {
        return stack.isEmpty
    }
    
    func size() -> Int {
        return stack.count
    }
    
    func push(object:AnyObject) {
        stack.append(object)
    }
    func pop() -> AnyObject? {
        if isEmpth() {
            return nil
        }else{
            return stack.removeLast()   //移除并返回最后一个元素
        }
    }
    
   
}

var stack = Stack()
stack.isEmpth()             //true
stack.push(object: UIColor(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0))
stack.push(object: UIColor(red: 1.0, green: 1.0, blue: 0.0, alpha: 1.0))
stack.pop()    //(r:1.0,g:1.0,b:0.0,a:1.0)
//queue队列先进先出
class Queue
{
    var queueArr:Array<Any>
    init() {
        queueArr = [Any]()
    }
    
    func isEmpty() -> Bool {
        return queueArr.isEmpty
    }
    func push(object: Any) {
        queueArr.append(object)
    }
    func pop() -> Any {
        return queueArr.removeFirst()
    }
}

var queue = Queue()
queue.isEmpty()
queue.push(object: 1)
queue.push(object: UIColor(red: 1.0, green: 2.0, blue: 3.0, alpha: 1.0))
queue.push(object: UIView(frame: CGRect(x: 1.0, y: 0.0, width: 22.0, height: 323.0)))
queue.pop()     //1


**链表**[http://c.biancheng.net/view/3338.html](http://c.biancheng.net/view/3338.html)
class linkedListNode                        //  创建一个类 作为节点,节点分为两个部分,content:数据域和nextNode:指向下一个节点的指针域
{
    var content: Int                        //  数据与
    var nextNode: linkedListNode?            // 指针域
    init(_ content: Int) {                  //  节点初始化
        self.content = content              //数据域
        self.nextNode = nil                 //指针域初始化为nil
    }
}

class linkedList
{
    var headerNode: linkedListNode?             //头结点
    var tailNode: linkedListNode?               //尾节点
    func appendToHeader(content: Int) {         //  头尾空就 头尾相同都为nil
        if headerNode == nil {
            headerNode = linkedListNode(content)
            tailNode = headerNode
        }else{
            let temporaryNode = linkedListNode(content)   //头部位空就让头往后移,新的节点作为头,指向原来的头节点
            temporaryNode.nextNode = headerNode
            headerNode = temporaryNode
        }
    }
    
    func appendToEnd(content: Int) {
        if tailNode == nil {
            tailNode = linkedListNode(content)
            headerNode = tailNode
        }else{
            tailNode?.nextNode = linkedListNode(content)   //尾节点不为nil,就指向下一个节点,下一个节点作为尾节点
            tailNode = tailNode?.nextNode
        }
    }
}
** swift冒泡排序 **

** 闭包 **
[闭包参考资料1](https://www.jianshu.com/p/7043ffaac2f2)
[闭包参考资料2](https://zhuanlan.zhihu.com/p/92464947)
上一篇下一篇

猜你喜欢

热点阅读