__nonnull 和 __nullable (Swift 和 Objective-C混编)

苹果在 Xcode 6.3 以后,为了解决 Swift 与 OC 混编时的问题,引入了一个 Objective-C 的新特性:nullability annotations。

这一新特性的核心是两个新的类型注释:__nullable 和 __nonnull。从字面上我们可以猜到,__nullable 表示对象可以是 NULL 或 nil,而 __nonnull 表示对象不应该为空。当我们不遵循这一规则时,编译器就会给出警告(编译器警告:Null passed to a callee that requires a non-null argument)。

引入 nullability annotations  新特性的原因:

在swift中,可以使用 ! 和 ? 来表示一个对象是 optional 的还是 non-optional,如 view! 和 view?,而在 Objective-C 中则没有这一区分,view 即可表示这个对象是optional,也可表示是non-optioanl。

这样就会造成一个问题:在 Swift 与 Objective-C 混编时,Swift 编译器并不知道一个 Objective-C 对象到底是 optional 还是 non-optional,因此这种情况下编译器会隐式地将 Objective-C 的对象当成是 non-optional。

我们来看看以下的实例:

 1 @interface StudentClass ()
 2
 3 @property (nonatomic, copy) NSArray *studentArray;
 4
 5 - (id)studentWithName:(NSString *__nonnull)name;
 6
 7 @end
 8
 9 @implementation StudentClass
10
11 - (void)testNullability {
12      [self studentWithName:nil];
13      // 编译器警告:Null passed to a callee that requires a non-null argument
14 }
15
16 - (id)studentWithName:(NSString *__nonnull)name {
17       return nil;
18 }
19
20 @end
不过这只是一个警告,程序还是能编译通过并运行。
事实上,在任何可以使用 const 关键字的地方都可以使用 __nullable 和 __nonnull,不过这两个关键字仅限于使用在指针类型上。而在方法的声明中,我们还可以使用不带下划线的 nullable 和 nonnull,如下所示:
- (nullable id)studentWithName:(NSString *nonnull)name;

在属性声明中,也增加了两个相应的特性,因此上例中的 studentArray 属性可以如下声明:

@property (nonatomic, copy, nonnull) NSArray *studentArray;

当然也可以用以下这种方式:

@property (nonatomic, copy) NSArray *__nonnull studentArray;

推荐使用 nonnull 这种方式,这样可以让属性声明看起来更清晰。

不过,为了安全起见,苹果还制定了几条规则:

  1. typedef 定义的类型的 nullability 特性通常依赖于上下文,即使是在 Audited Regions 中,也不能指定它为 nonnull。
  2. 复杂的指针类型(如id *)必须显示去指定是 nonnull 还是 nullable。例如,指定一个指向 nullable 对象的 nonnull 指针,可以使用 "__nullable id *__nonnull"。
  3. 我们经常使用的 NSError ** 通常是被假定为一个指向 nullable NSError 对象的 nullable 指针。

因为 Nullability Annotations 是 Xcode 6.3 新加入的,所以我们需要考虑之前的老代码。实际上,苹果已以帮我们处理好了这种兼容问题,我们可以安全地使用它们:

  1. 老代码仍然能正常工作,即使对 nonnull 对象使用了 nil 也没有问题。
  2. 老代码在需要和 Swift 混编时,在新的 Swift 编译器下会给出一个警告。
  3. nonnull 不会影响性能,事实上,我们仍然可以在运行时去判断我们的对象是否为 nil。

事实上,我们可以将 nonnull/nullable 与我们的断点和异常一起看待,其需要处理的问题都是同一个:违反约定是一个程序员的错误;特别是,返回值是我们可控的东西,如果返回值是 nonnull 的,则我们不应该返回 nil,除非是为了向后兼容。

时间: 2024-10-11 04:13:22

__nonnull 和 __nullable (Swift 和 Objective-C混编)的相关文章

Swift与OC的混编

自04年苹果推出了Swift之后,确实很快就受到许多开发者的欢迎但在实际开发时,可能有许多第三方库并未实现代码Swift化,这时就需要Swift与OC的混编技巧: 1.在.h文件中引用Swift的类和方法,需要在.h文件中进行引用,需要注意引用格式: #import "yourProjectName-swift.h" 2.在Build Settings -> Packaging -> Defines Module 改为YES 3.在Swift中引用OC的方法与类,则需在 B

iOS开发--Swift 如何完成工程中Swift和OC的混编桥接(Cocoapods同样适用)

由于SDK现在大部分都是OC版本, 所以假如你是一名主要以Swift语言进行开发的开发者, 就要面临如何让OC和Swift兼容在一个工程中, 如果你没有进行过这样的操作, 会感觉异常的茫然, 不用担心, 整个过程非常简单. 在已有的Swift工程中, 当你需要使用OC的类文件, 或者需要集成SDK时, 创建你需要的OC的类文件, 创建结束后, 会提示生成一个桥接头文件, 点击蓝色Create按钮. *OC工程也一样, 只是要进行相反的操作, 在需要创建OC文件的时候创建一个Swift的文件 *创

obeject-c 与 swift 混编

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px ".PingFang SC"; color: #454545 } p.p2 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px "Helvetica Neue"; color: #454545 } span.s1 { font: 12.0px "Helvetica Neue" } span.s2 {

详解 swift3.0 和 OC 的混编

前言: 我们在一些情况下,仅仅使用swift 是无法完成一个项目的,在swift项目中必要用到 OC 实现一些功能,比如,项目要使用一些第三方的框架,但这个第三方的框架却是用 OC 实现的,或者你的项目必须调用原有项目的部分功能,而原来的项目也是用 OC 实现的.在这样的一些背景下,你就必须要实现这两种语言的混编.反过来也一样,比如开发者打算用swift实现一些新的功能要用到三方框架,而人家是使用swift写的,而你的项目确实OC的,这时候你也得实现一个混编.下面我们分两种情况分别说明一些. 一

iOS开发——技术精华Swift篇&Swift 2.0和Objective-C2.0混编之第三方框架的使用

Swift 2.0和Objective-C2.0混编之第三方框架的使用 swift 语言是苹果公司在2014年的WWDC大会上发布的全新的编程语言.Swift语言继承了C语言以及Objective-C的特性,且克服了C语言的兼容性问题.Swift语言采用安全编程模式,且引入了多种新功能,使得编程工作更加简便,灵活! 2015年6月9日苹果又一次给所有开发之者带来了一个惊喜,那就是今年年底swift讲开源,者队iOS开发着来说无疑是一个值得兴奋的消息,可是就在这短短的几个月里面swift吸引了越来

Swift和Objective-C混编注意事项

前言 Swift已推出数年,与Objective-C相比Swift的语言机制及使用简易程度上更接地气,大大降低了iOS入门门槛.当然这对新入行的童鞋没来讲,的确算是福音,但对于整个iOS编程从业者来讲,真真是,曾几何时"高大上",转瞬之间"矮矬穷".再加上培训班横行,批量批发之下,iOS再也看不到当年的辉煌.iOS10推出后,紧跟着Xcode8也推送了更新,细心者会发现,Xcode8下iOS版本最低适配已变为iOS8.0,加上Swift版本趋于稳定,从某种意义上讲,

Swift和Objective-C混编的注意啦

文/仁伯安(授权) 原文链接:http://www.jianshu.com/p/2ed48b954612 前言 Swift已推出数年,与Objective-C相比Swift的语言机制及使用简易程度上更接地气,大大降低了iOS入门门槛.当然这对新入行的童鞋没来讲,的确算是福音,但对于整个iOS编程从业者来讲,真真是,曾几何时"高大上",转瞬之间"矮矬穷".再加上培训班横行,批量批发之下,iOS再也看不到当年的辉煌. 往事不再提,事还是要做滴.iOS10推出后,紧跟着X

[ios][swift]swift混编

参考:http://www.tuicool.com/articles/QZNrErM 即使你尽量用Swift编写iOS程序,难免会遇到部分算法是用C++语言编写的.那你只能去问问”度娘“或“狗哥”怎么用 Swift 调用C++算法. 一,C,C++, Objective-C,Swift有什么关系,还有什么是混编 -.-? 1. 当然是兄弟关系,虽然Objective-C是扩充C的 面向对象 编程语言,C++是在C语言的基础上开发的一种通用 编程语言 .Swift是由苹果公司推出有意让其与Obje

Swift和Objective-C混编

Swift和Objective-C混编的注意啦 2016-10-19 13:29 编辑: 不灭的小灯灯 分类:iOS开发 来源:仁伯安的简书 0 OCSwift混编 前言 Swift已推出数年,与Objective-C相比Swift的语言机制及使用简易程度上更接地气,大大降低了iOS入门门槛.当然这对新入行的童鞋们来讲,的确算是福音,但对于整个iOS编程从业者来讲,真真是,曾几何时"高大上",转瞬之间"矮矬穷".再加上培训班横行,批量批发之下,iOS再也看不到当年的