关于Objective-C语言的增强- Objective-C API中可以表示参数,返回值,属性,变量等等的“nullability”属性。比如,下面是表达很多UITableView API的为空特性:
- -(void)registerNib:(nonnull UINib *)nib forCellReuseIdentifier:(nonnull
- SString *)identifier;
- -(nullable UITableViewCell *)cellForRowAtIndexPath:(nonnull
- SIndexPath)indexPath;
- @property (nonatomic, readwrite, retain, nullable) UIView *backgroundView;
这个nullability标示符影响了Objective-C API在Swift的可选类型值,nonnull标示符标示的类型将会以非可选的类型的导入,这个用来替代隐式解封可选类型如(e.g., UINib!)。而nullable标示符标示的类型则会以可选类型导入(如UITableViewCell?),所以下面的API在Swift中表现如下: - func registerNib(nib: UINib, forCellReuseIdentifier identifier: String)
- func cellForRowAtIndexPath(indexPath: NSIndexPath) -> UITableViewCell?
- var backgroundView: UIView?
- 可空特性标示符也可以用在指针类型,包括C指针,block指针和C++成员指针,使用双下划线方式,比如:
- void enumerateStrings(__nonnull CFStringRef (^ __nullable callback)(void));
这里,它自身的回调函数是nullable的,但是它的回调函数的返回类型为nonnull,所以这个API在Swift以如下方式使用: - func enumerateStrings(callback: (() -> CFString)?)
总的来说,可空特性标示符有三种,可以用双下划线(用在任何指针类型),或者没有下划线的(用在Objective-C属性,方法结果类型或者方法参数类型)。 Type qualifier spelling
| Objective-C property/method spelling
| Swift view
| Meaning
| __nonnull
| nonnull
| Non-optional, 如: UINib
| 该值永远不会为nil(有一种例外是可能参数传递时传入的消息为空)
| __nullable
| nullable
| Optional, 如:UITableViewCell?
| 该值可能为nil
| __null_unspecified
| null_unspecified
| 隐式解封可选类型如, NSDate!
| 不确定该值是否为空(很少见)
|
- 特别是在Objective-C API中,很多指针倾向于nonnull,因此Objective-C提供了“audited”域(通过新的#pragma),它会认为未被标注的指针为nonnull,比如下面的例子等同于上面第一个例子,但是它用的是“audited”域来简化语句表达:
- #pragma clang assume_nonnull begin
-
- -(void)registerNib:(UINib *)nib forCellReuseIdentifier:(NSString
- *)identifier;
- -(nullable UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath)indexPath;
- @property (nonatomic, readwrite, retain, nullable) UIView *backgroundView;
-
- #pragma clang assume_nonnull end
- 为了保证代码的连续性,我们强烈建议你在所有的Objective-C头文件使用“audited”域来表述其api的可空性,同时避免null_unspecified情况,建议使用在将可空性引入到现有的头文件时采用该功能作为过渡工具。
- Objective-C增加的nullability注解不会影响它的向后兼容性也不会影响代码的编译。比如nonnull在有些情况下依然可以以nil结束,诸如消息路由到一个为nil的接收器,但是,nullability注解只是提高Swift的编程体验,它会在Objective-C中产生一个新的警告,诸如朝一个nonnull的参数赋一个nil的话,这使得Objective-c API更加高效以及使用的正确。
- Objective-C可以通过null_resettable来表达属性的空属性,该属性setter访问器允许将其设置为nil(设置该属性为默认值),但是它的getter访问器不会提供一个nil值(因为它提供了默认值),有一个这样的属性如UIView’s tintColor,如果没有tint颜色指定时它会提供一个默认的tint颜色值,如:
- @property (nonatomic, retain, null_resettable) UIColor *tintColor;
这样的API在Swift使用隐式强制解封的方法使用: - C指针类型的参数或者Block指针类型可以使用noescape新属性标志,它用来标明这个指针参数不会离开这个函数或者方法而使用。这种情况下,可以安全的传递一个局部变量地址,noescape block指针在Swift中将会被映射为@noescape参数:
- void executeImmediately(__attribute__((noescape)) void (^callback)(void);
将被影射到Swift为: - func executeImmediately(@noescape callback: () -> Void)
- LLDB现在包含了一个printf()函数去计算C/C++/Objective-C表达式,这个将在arm64设备上提升表达式计算的体验,但是可能和用户在.lldbinit定义的表达式前缀冲突,如果你发现在表达式计算时出现错误,这可能就是root cause。
- XCode 6.3将Apple LLVM编译器更新为6.1.0,这个新的编译器版本包含了对C++14标准的全部支持,包括大量的增强的警告诊断和新的优化,对于arm64架构的支持进行了有效的重构来支持ARM的实现, 这个将明显影响矩阵内联函数计算。
- 为arm64 vfma/vfms内联函数预定的参数被移除,虽然这个改变不会产生一个编译时错误,但是它会中断代码运行时操作,我们需要明确这个变化来减少风险。默认的,编译器现在会对使用这种内联属性提供警告并维持固有的行为,在尽可能的情况下,你需要接受这个变化并且定义USE_CORRECT_VFMA_INTRINSICS宏为1告诉编译器接收警告,当然你也可以可以USE_CORRECT_VFMA_INTRINSICS宏为0来屏蔽警告并保持固有行为。但是请不要保留这样的代码太久,因为我们计划在未来的版本中移除对这种旧行为的支持。
- 含有自动尺寸标志的视图以及包含在UITableView、UICollectionView或NSScrollView的视图在打开文档时不会再出现对齐错误。
|