Swift(随笔,记录一下自己不太明白的方便以后会看)

// MARK:- 事件监听
 composeBtn.addTarget(self, action: #selector(MainViewController.composeBtnClick), for: .touchUpInside)


 extension BaseViewController {
    // 事件监听本质发送消息.但是发送消息是OC的特性
    // 将方法包装成@SEL --> 类中查找方法列表 --> 根据@SEL找到imp指针(函数指针) --> 执行函数
    // 如果swift中将一个函数声明称private,那么该函数不会被添加到方法列表中
    // 如果在private前面加上@objc,那么该方法依然会被添加到方法列表中
    // 如果此方法和button的监听 在同一个拓展中,就不用加@objc fileprivate  但是这方法能被其他类调用
    @objc fileprivate func composeBtnClick() {
        print("composeBtnClick")
    }
}

在swift中的初始化

在swift中 在类名的后面跟上()就相当于OC中的 alloc init

Swift中基本运算

Swift中在进行基本运算时必须保证类型一致,否则会出错
相同类型之间才可以进行运算
因为Swift中没有隐式转换
数据类型的转化
Int类型转成Double类型:Double(标识符)
Double类型转成Int类型:Int(标识符)

let a = 10
let b = 3.14
// 错误写法
// let c = a + b
// let c = a * b
// 正确写法
let c = Double(a) + b

逻辑分支

和OC中if语句有一定的区别判断句可以不加() 在Swift的判断句中必须有明确的真假不再有非0即真 必须有明确的Bool值 Bool有两个取值:false/true

let a = 10
// 错误写法:
//if a {
// print("a")
//}
// 正确写法
if a > 9 { 
print(a)
}

switch支持区间判断

什么是区间? 通常我们指的是数字区间:0~10,100~200 swift中的区间常见有两种 开区间:0..<10 表示:0~9,不包括10 闭区间:0...10 表示:0~10

定义可选类型

定义一个可选类型有两种写法
最基本的写法
语法糖(常用)

// 错误写法
// let string : String = nil
// 正确写法:
// 注意:name的类型是一个可选类型,但是该可选类型中可以存放字符串.
// 写法一:定义可选类型
let name : Optional = nil
// 写法二:定义可选类型,语法糖(常用)
let name : String? = nil

// 注意:如果可选类型为nil,强制取出其中的值(解包),会出错

引用类型(指针的传递)

默认情况下,函数的参数是值传递.如果想改变外面的变量,则需要传递变量的地址
必须是变量,因为需要在内部改变其值
Swift提供的inout关键字就可以实现
对比下列两个函数

// 函数一:值传递
func swap(var a : Int, var b : Int) {
 let temp = a;
 a = b;
 b = temp
 print("a:\(a), b:\(b)"
)}
var a = 10
var b = 20
swap(a, b: b)
print("a:\(a), b:\(b)")

// 函数二:指针的传递
func swap1(inout a : Int, inout b : Int) {
   let temp = a 
  a = b
   b = temp
   print("a:\(a), b:\(b)")
}
swap1(&a, b: &b)
print("a:\(a), b:\(b)")

定义类的属性

类属性是与类相关联的,而不是与类的实例相关联
所有的类和实例都共有一份类属性.因此在某一处修改之后,该类属性就会被修改
类属性的设置和修改,需要通过类来完成
类属性使用static来修饰

监听属性的改变

在OC中我们可以重写set方法来监听属性的改变
Swift中可以通过属性观察者来监听和响应属性值的变化
通常是监听存储属性和类属性的改变.(对于计算属性,我们不需要定义属性观察者,因为我们可以在计算属性的setter中直接观察并响应这种值的变化)
我们通过设置以下观察方法来定义观察者
willSet:在属性值被存储之前设置。此时新属性值作为一个常量参数被传入。该参数名默认为newValue,我们可以自己定义该参数名
didSet:在新属性值被存储后立即调用。与willSet相同,此时传入的是属性的旧值,默认参数名为oldValue
willSet与didSet只有在属性第一次被设置时才会调用,在初始化时,不会去调用这些监听方法
监听的方式如下:
监听age和name的变化

class Person : NSObject {
    var name : String? {
        // 可以给newValue自定义名称
        willSet (new){ // 属性即将改变,还未改变时会调用的方法
            print(name ?? "HF")
            print(new ?? "")
        }
        // 可以给oldValue自定义名称
        didSet (old) { // 属性值已经改变了,会调用的方法
            print(name ?? "HF")
            print(old ?? "old")
        }
    }
    var age : Int = 0
    var height : Double = 0.0
}

let p : Person = Person()

// 在赋值时,监听该属性的改变
// 在OC中是通过重写set方法
// 在swift中,可以给属性添加监听器
p.name = "why"
Swift(随笔,记录一下自己不太明白的方便以后会看)_第1张图片
D2ECD09B-98B0-4F79-B10E-59390C0F4384.png

swift中解决循环引用的方式

  • 方案一:
    • 使用weak,对当前控制器使用弱引用
      但是因为self可能有值也可能没有值,因此weakSelf是一个可选类型,在真正使用时可以对其强制解包(该处强制解包没有问题,因为控制器一定存在,否则无法调用所在函数)
// 解决方案一:
 weak var weakSelf = self 
httpTool.loadData { 
        print("加载数据完成,更新界面:", NSThread.currentThread())        
        weakSelf!.view.backgroundColor = UIColor.redColor() 
}
  • //方案二:
    • 和方案一类型,只是书写方式更加简单
      可以写在闭包中,并且在闭包中用到的self都是弱引用
httpTool.loadData {[weak self] () -> () in 
print("加载数据完成,更新界面:", NSThread.currentThread()) 
self!.view.backgroundColor = UIColor.redColor() 
}
  • 方案三:(不推荐使用)
    • 使用关键字unowned
      从行为上来说 unowned 更像OC中的 unsafe_unretained
      unowned 表示:即使它原来引用的对象被释放了,仍然会保持对被已经释放了的对象的一个 "无效的" 引用,它不能是 Optional 值,也不会被指向 nil
httpTool.loadData {[unowned self] () -> () in 
print("加载数据完成,更新界面:", NSThread.currentThread()) 
self.view.backgroundColor = UIColor.redColor()
 }

你可能感兴趣的:(Swift(随笔,记录一下自己不太明白的方便以后会看))