Swift 3.0 预告 - 将 Objc 库转换成更符合 Swift 语法风格的形式

Swift 3.0 预告 - 将 Objc 库转换成更符合 Swift 语法风格的形式,第1张

概述原因 这个源于一个编号为 SE-0005 的提案,并且已经审核通过。这个方案的提出,源于这样一个痛点。 Swift 应用于 iOS App 开发,就免不了会依赖于原生的 Cocoa Touch 库。而由于历史原因,大家也都知道, iOS 原生库大多时基于 Objc 来实现的。所以他们的编码规范也都遵循着 Objc 的规范,诸如函数,方法的命名规则这些,都有自己的一套标准。 而 Swift 3.0

原因


这个源于一个编号为 SE-0005 的提案,并且已经审核通过。这个方案的提出,源于这样一个痛点。 Swift 应用于 iOS App 开发,就免不了会依赖于原生的 Cocoa touch 库。而由于历史原因,大家也都知道, iOS 原生库大多时基于 Objc 来实现的。所以他们的编码规范也都遵循着 Objc 的规范,诸如函数,方法的命名规则这些,都有自己的一套标准。


而 Swift 3.0 也发布了自己的 API 设计规范,同时 Objc 也有自己的设计规范,这样一来我们使用 Swift 开发 iOS App 的时候,其实总是在游走于两套规范的 API 之间,对开发者的体验嘛,就不是很好了。


例子


咱们用一个实际的例子来说明这个问题。 比如 Nsstring 有这样一个方法:



let content = ListItemVIEw.text.stringByTrimmingCharactersInSet(
  NSCharacterSet.whitespaceAndNewlineCharacterSet())



stringByTrimmingCharactersInSet 会剪掉字符串头尾中的某些字符。从这个方法名中,明显的可以看出它是以 Objc 规范来命名的。


如果以 Swift 的编码规范,这个方法其实应该这样命名:



let content = ListItemVIEw.text.trimming(.whitespaceAndNewlines)



从这里可以看出,objc 的命名方式,很多会把函数的返回值类型,以及参数类型都包含在函数名里面。比如我们上面的stringByTrimmingCharactersInSet 方法。但这和 Swift 命名规则就不同了。而且随着 Swift 规范的清晰,这个问题就越来越凸显出来了。


所以 Swift 3.0 才会将这个问题提上日程,并在这个版本中准备解决这个问题。


规则


解决这个问题,肯定不能手动的替换。因为系统库的方法实在太多了,所以就需要总结出一系列替换规则。根据这些规则将相应的标识替换完成。


那么 Swift 具体是怎么做的呢, 咱们来了解一下。


扩大 swift_name 编译属性的应用范围 - 这个涉及到 Swift 底层的概念,当我们将 Objc 的 API 导入到 Swift 的时候,我们是可以指定一个编译属性swift_name 的。而这个编译属性,可以将 Objc 中的标识名称在 Swift 中以不同的名字表现出来。但在之前的版本中,这个编译属性只能对枚举项和工厂方法有效,这次将会扩大它的范围。


去除多余的类型名称 - Objc 的编码规范中,会建议在方法名称中将参数名和类型也表示出来,而这个在 Swift 中就是多余的,我们前面那个例子也演示了。这个也是着重处理的点。


添加默认参数 - 对于 Objc 需要默认参数的地方,会在 Swift 中添加上默认参数,比如一些选项参数:



NSJsONSerialization.JsONObjectWithData(data,options: NSJsONReadingOptions.AllowFragments)



这个 option 参数就会提供默认参数。


添加第一个参数的参数标签 - 为方法的第一个参数添加合适的参数标签。


在布尔属性前面加上 is - 在最新的 Swift 规范中,需要在布尔属性前面加上 is,而 Objc 规范恰巧不建议使用 is,所以在 Swift 3 中会将 Objc 迁移过来的布尔属性,按照 Swift 规范来进行修改。可以参考 Swift 规范中关于布尔属性的部分内容。


值类型变成小写 - 会将 Objc 的属性值以小写开头, 比如 URLHandler 会变为 urlHandler.


下面是一个官方文档中给出的转换的例子:



class UIBezIErPath : NSObject,NScopying,0);">NSCoding {
 convenIEnce init(ovalInRect: CGRect)
 func movetoPoint(_: CGPoint)
 addlinetoPoint(addCurvetoPoint(_: CGPoint,controlPoint1: CGPoint,controlPoint2: CGPoint)
 addQuadCurvetoPoint(  appendpath(_: UIBezIErPath)
 bezIErPathByreversingPath() -> UIBezIErPath
 applytransform(_: CGAffinetransform)
 var empty: Bool { get }
 containsPoint(_: CGPoint) -> Bool
 fillWithBlendMode(_: CGBlendMode,Alpha: CGfloat)
 strokeWithBlendMode(copyWithZone(_: NSZone) -> AnyObject
 encodeWithCoder(_: NSCoder)
}



转换后:



init(ovalIn rect: CGRect)
 move(to point: CGPoint)
 addline(to point: CGPoint)
 addCurve(to endPoint: CGPoint,controlPoint1 controlPoint1: CGPoint,controlPoint2 controlPoint2: CGPoint)
 addQuadCurve(to endPoint: CGPoint,controlPoint controlPoint: CGPoint)
 append(_ bezIErPath: UIBezIErPath)
 reversing() -> UIBezIErPath
 apply(_ transform: CGAffinetransform)
 var isEmpty: Bool { contains(_ point: CGPoint) -> Bool
 fill(_ blendMode: CGBlendMode,Alpha Alpha: CGfloat)
 stroke(copy(with zone: NSZone = nil) -> AnyObject
 encode(with aCoder: NSCoder)
}



是不是感觉方法名清晰很多呢。


总结


以上就是 Swift 3 对 Objc 依赖库中的优化了,这次优化后,我们以后在用 Swift 来开发 iOS App 的时候,就不会再混合两种代码风格啦。



总结

以上是内存溢出为你收集整理的Swift 3.0 预告 - 将 Objc 库转换成更符合 Swift 语法风格的形式全部内容,希望文章能够帮你解决Swift 3.0 预告 - 将 Objc 库转换成更符合 Swift 语法风格的形式所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1025721.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-23
下一篇 2022-05-23

发表评论

登录后才能评论

评论列表(0条)