以下是迁移公司项目代码至Swift3的时,遇到较多的问题的一个总结.
1.首当其冲的就是闭包的修改。
升级完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中就没有名字啦
),只有参数的类型,我们需要自己来定义参数的名称.
2.在Swift2.3中我们函数在被调用时的第一个参数名会被省略,除非在前面在此定义eq:
//这样才会在调用的时候显示参数名 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冗长的方法命名,精简了语意,但是可读性还需要长时间的检验吧
3.使用NSDictionary的修改
dict.setObject(true, forKey: "state")
dict.setObject(num, forKey: "key")
在之前我们一直使用NSDictionary(~~因为从OC转过来感觉还是NSarray和NSDictionary用起来顺手的 ),用来设置key的时候。现在需要添加NSCopying ,所以我都改成Dictionary啦哈哈。现在我们也应该在之后写代码的时候避免使用NSString,NSArray, NSDictionary等因为现在更加不方便了
4.泛型
//swift2.2
var selectResult:PHFetchResult?
//swift3
var selectResult:PHFetchResult?
这个是项目中图片管理器所用到的,现在就是需要在PHFetchResult后面告诉它是什么类型,也可以是AnyObject
这个后面还需要详细的介绍。给自己挖个坑
5.没有了CGRectMake 改用CGRect.init来初始化或者我们写一个他的扩展.来模拟之前的CGRectmake
//用来代替,修改的CGRectMake
func CGRectMake(_ x:CGFloat,_ y:CGFloat,_ width:CGFloat,_ height:CGFloat)->CGRect
{
return CGRect.init(x: x, y: y, width: width, height: height)
}
6.关于颜色的初始化方法UIColor.color都去掉了括号,并且color的后缀页去掉了,新添加了Url类,也是为了脱离OC的NSUrl吧.
7.GCD的改变 更加Swift化.
DispatchQueue.main.async {
let controller = LoginViewController()
self.present(controller, animated: true, completion: nil)
}
其实GCD的用法没有太多的改变,只是写法变的更加Swift,去掉了之前C语言的形式,多写读多熟悉应该就好了。
9.NSString操作的变化
//swift2.2
let ch = (pinYinString as NSString).character(at: 0)
//swift3
let ch=pinYinString?.unicodeScalars[(pinYinString?.unicodeScalars.startIndex)!]
因为我需要取到拼音的首字母来进行排序,所以需要获取到首字母的ASCII码。所以使用NSString更方便。但是现在不能这样用了,所以我们只能使用Swift中的这个unicodeScalars来获取啦。
8.枚举变成了小写,自己定义的时候是大写当他变成.语法的时候Xcode页把它变成了小写
以上只列举去我在修改项目时所遇到的较多次的问题,现在项目还没有修改完,只是修改了一大部分(
其实没有什么很难修改的问题,只是修改的地方太多,工作量较大
),我也会在接下来更新遇到较多的问题~~
可以下载我们的APP茶虫使用一下呦~
更多Swift3的改动详情请阅读Swift官方博客和Swift3中文文档