升级完Xcode8之后根据提示会默认帮你进行一些修改。但是修改完成还有500+多个错误很大一部分是闭包的修改,我的内心是这样的。
在Swift2.3中我们写闭包是这样写:
//Swift 2.2
typealias detailCollectBlock = (state:Bool)->Void
var detailCollect:detailCollectBlock?
func detailCollect(detailCollect:detailCollectBlock)
{
self.detailCollect = detailCollect
}
//在需要的时候调用
self.detailCollect?(state:true)
//
controller.detailPraise({ (state) in
model.isPraise = (state ? "1" : "0")
})
//Swift3中的 使用方法1
typealias detailCollectBlock = (Bool)->Void
var detailCollect:detailCollectBlock?
func detailCollect(detailCollect:@escaping detailCollectBlock)
{
self.detailCollect = detailCollect
}
//在需要的时候调用
self.detailCollect?(true)
//在上页面回调接收的时候的用法
controller.detailPraise(detailPraise: { (<#Bool#>) in
model.isPraise = (state ? "1" : "0")
})
//使用方法2
typealias detailCollectBlock = (_ state:Bool)->Void
var detailCollect:detailCollectBlock?
func detailCollect(_ detailCollect:@escaping detailCollectBlock)
{
self.detailCollect = detailCollect
}
//在需要的时候调用
self.detailCollect?(state:true)
//
controller.detailPraise({ (state) in
model.isPraise = (state ? "1" : "0")
})
这个时候大家应该就可以从代码中发现,swift3中需要定义闭包的时候不需要命名参数名,只需要告诉参数类型即可.
现在迁移我们也可以使用方法2,这时我们的参数在使用时还是省略的(就和2.2时使用相同),外部调用闭包的时候就不需要在修改了。这样可以减少很多工作量,因为项目中的闭包实在是太多了..
如果闭包不是在当前作用域内执行而是还要继续传递到别的函数里的话, 那就必须加上@escaping
,本身的意思是逃逸的
别接收回调的地方也和swift2.2不同,回调方法中会有block的名字,但是没有参数名了(方法2中就没有名字啦
),只有参数的类型,我们需要自己来定义参数的名称.
详情见SE-0103和SE-0118
//这样才会在调用的时候显示参数名 swift2.2时
func addCollect(detailId detailId)
在Swift3中我们不需要在这样做了。会一直带有第一个参数名
3.UIControlState等的表示状态的常量 都变成了首字母小写
//Swift2.2
self.toolsView?.praiseButton.setImage(UIImage.init(named: "tool_icon_like_normal"), forState: .Normal)
self.phone?.componentsSeparatedByString() //swift2.2
//swift3
self.toolsView?.praiseButton.setImage(UIImage.init(named: "tool_icon_like_normal"), for: .normal)
self.phone?.components(separatedBy: "-") //swift3
这样做也是为了脱离OC冗长的方法命名,精简了语意,但是可读性还需要长时间的检验吧
dict.setObject(true, forKey: "state")
dict.setObject(num, forKey: "key")
在之前我们一直使用NSDictionary(因为从OC转过来感觉还是NSarray和NSDictionary用起来顺手的 ),用来设置key的时候。现在需要添加NSCopying ,所以我都改成Dictionary啦哈哈。现在我们也应该在之后写代码的时候避免使用NSString,NSArray, NSDictionary等因为现在更加不方便了~~
//swift2.2
var selectResult:PHFetchResult?
//swift3
var selectResult:PHFetchResult<PHAsset>?
这个是项目中图片管理器所用到的,现在就是需要在PHFetchResult后面告诉它是什么类型,也可以是AnyObject
这个后面还需要详细的介绍。给自己挖个坑
//用来代替,修改的CGRectMake
func CGRectMake(_ x:CGFloat,_ y:CGFloat,_ width:CGFloat,_ height:CGFloat)->CGRect
{
return CGRect.init(x: x, y: y, width: width, height: height)
}
DispatchQueue.main.async {
let controller = LoginViewController()
self.present(controller, animated: true, completion: nil)
}
其实GCD的用法没有太多的改变,只是写法变的更加Swift,去掉了之前C语言的形式,多写读多熟悉应该就好了。
//swift2.2
let ch = (pinYinString as NSString).character(at: 0)
//swift3
let ch=pinYinString?.unicodeScalars[(pinYinString?.unicodeScalars.startIndex)!]
因为我需要取到拼音的首字母来进行排序,所以需要获取到首字母的ASCII码。所以使用NSString更方便。但是现在不能这样用了,所以我们只能使用Swift中的这个unicodeScalars来获取啦。