Xcode8和swift3更新笔记(一)

个人笔记,遇到什么写什么,各位同学不要介意!

1、升级swift3 后突然发现extension中的一些private方法不调能用了!!!急急急~

原来 private都改成了fileprivate。本来不用private也不会对程序的编译运行有任何影响,private只是为了保证代码外部可读性而准备的,而现在有了fileprivate以后,private变得更加“私有”。现在的private方法和对象,只能在大括号中访问,即便是这个类的extension中,也不能访问private。也就是说private的作用于是当前类(不包含扩展),而fileprivate的作用域,则和以前的private一样,当前类、继承类、扩展类都OK

2、 闭包的escaping和non-escaping类型
这个类型决定了闭包是否在调用他的函数(或其他)返回时就销毁(?),escaping是不销毁的意思,non-escaping是保留的意思。一般在网络方法中,闭包一般在其他线程中执行,并且在函数返回时还没有执行完毕,这里种情况应该使用escaping类型。使用方法是在闭包前面加@escaping。反之同理。
那么为什么在swift2之前都不需要加呢,因为swift2之前默认都是escaping类型,而swift3以后默认是non-escaping。在合理的情况下,使用non-escaping类型的闭包更节省内存,而且,在闭包内可以不用再加self关键字了


3、info.plist中的privacy key

在iOS旧版本中都会,凡是涉及到隐私相关权限(例如录音、摄像之类的)的访问,都会提示是否允许访问。在plist有一系列privacy - XXXDescription的key作为权限询问提示的文字,旧版iOS中这些是选填的,iOS10里面如果没有填写又访问了相关权限,程序会崩溃。

4、@noescape走了 @escaping来了

在之前,一个函数的参数的闭包的捕捉策略默认是escaping,如果是一个非逃逸闭包需要显示的添加声明@noescape。简单的介绍就是如果这个闭包是在这个函数结束前内被调用,就是非逃逸的即noescape。如果这个闭包是在函数执行完后才被调用,调用的地方超过了这函数的范围,所以叫逃逸闭包。

举个例子就是我们常用的masonry或者snapkit的添加约束的方法就是非逃逸的。因为这闭包马上就执行了。

  public func snp_makeConstraints(file: String = #file, line: UInt = #line, @noescape closure: (make: ConstraintMaker) -> Void) -> Void {
        ConstraintMaker.makeConstraints(view: self, file: file, line: line, closure: closure)
    }

网络请求请求结束后的回调的闭包则是逃逸的,因为发起请求后过了一段时间后这个闭包才执行。比如这个Alamofire里的处理返回json的completionHandler闭包,就是逃逸的。

public func responseJSON(
        queue queue: dispatch_queue_t? = nil,
        options: NSJSONReadingOptions = .AllowFragments,
        completionHandler: Response -> Void)
        -> Self
    {
        return response(
            queue: queue,
            responseSerializer: Request.JSONResponseSerializer(options: options),
            completionHandler: completionHandler
        )
    }

就像我之前写的那篇标题,很多人在写闭包参数的时候总是忽略去判断这个闭包是否是逃逸的。这对闭包的内存管理优化不太友好,都被当做了逃逸闭包处理。所以在3中做出了一个对调的改变:所有的闭包都默认为非逃逸闭包,不再需要@noescape;如果是逃逸闭包,就用@escaping表示。比如下面的一段代码,callBack在函数执行完后1秒才执行,所以是逃逸闭包。
func startRequest(callBack: ()->Void ) {
    DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + 1) { 
        callBack()
    }
}

这样就需要显示的声明@escaping才能编译通过。








你可能感兴趣的:(Swift)