iOS开发——新特性篇&swift新特性(__nullable和__nonnull)

swift新特性(__nullable和__nonnull)

最近在看老师写代码的时候经常遇到两个陌生的关键字,但是当我在我的电脑上敲得时候就是敲不出,后来才知道这是为了swift与OC混编的时候产生的一个新特性,就很认真的研究了一下。

在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。

为了解决这个问题,苹果在Xcode 6.3引入了一个Objective-C的新特性:nullability annotations。

这一新特性的核心是两个新的类型注释:__nullable__nonnull。从字面上我们可以猜到,__nullable表示对象可以是NULL或nil,而__nonnull表示对象不应该为空。当我们不遵循这一规则时,编译器就会给出警告。

我们来看看以下的实例,

 1 @interface TestNullabilityClass ()
 2 @property (nonatomic, copy) NSArray * items;
 3 - (id)itemWithName:(NSString * __nonnull)name;
 4 @end
 5 @implementation TestNullabilityClass
 6 ...
 7 - (void)testNullability {
 8     [self itemWithName:nil];    // 编译器警告:Null passed to a callee that requires a non-null argument
 9 }
10 - (id)itemWithName:(NSString * __nonnull)name {
11     return nil;
12 }
13 @end

不过这只是一个警告,程序还是能编译通过并运行。

事实上,在任何可以使用const关键字的地方都可以使用__nullable和__nonnull,不过这两个关键字仅限于使用在指针类型上。而在方法的声明中,我们还可以使用不带下划线的nullable和nonnull,如下所示:


1

- (nullable id)itemWithName:(NSString * nonnull)name

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


1

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

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


1

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

推荐使用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-11-09 05:03:24

iOS开发——新特性篇&swift新特性(__nullable和__nonnull)的相关文章

iOS开发——实战OC篇&环境搭建之Xib(玩转UINavigationController与UITabBarController)

iOS开发——实战OC篇&环境搭建之Xib(玩转UINavigationController与UITabBarController) 前面我们介绍了StoryBoard这个新技术,和纯技术编程的代码创建界面,本篇我们将介绍一个老的技术,但是在很多的公司或者库里面还是使用这个技术,既然如此它肯定有他的好处,至于好处这里我就不一一介绍了.在Xcode5之前是只能使用Xib或者代码的,而代码又对于很多初学者来说算是一个难题.毕竟不知道怎么下手.所以我就总结了一下这段时间自己编写程序的一个实例来说明怎么

iOS开发——实战OC篇&环境搭建之纯代码(玩转UINavigationController与UITabBarController)

iOS开发——实战OC篇&环境搭建之纯代码(玩转UINavigationController与UITabBarController) 这里我们就直接上实例: 一:新建一个项目singleView Controller,命名未iCocos 二:由于我们使用的纯代码实现的,所以删除其中的StoryBoard和Viewtroller的两个文件 三:新建一个继承自TabBar Controller的类,我们命名问iCocos ViewController 三:在Appdelegate的实现文件中导入刚刚

iOS开发入门——17条 Swift 最佳实践规范(下)

文章来源:http://www.zretc.com/technologyDetail/433.html 承接上文:iOS开发入门--17条 Swift 最佳实践规范(上) 9.单例(Singletons) 在Swift中单例是很简单的: class ControversyManager { static let sharedInstance = ControversyManager()} Swift 的 runtime 会保证单例的创建并且采用线程安全的方式访问. 单例通常只需要访问"share

学习IOS开发网络多线程篇--NSThread/GCD/

NSThread:利用NSThread创建和启用一个线程 1. NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];,调用后调用[thread start]; 2. 创建线程后自动启动线程 ,[NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil]; 3. 隐式创建

IOS开发数据存储篇—IOS中的几种数据存储方式

IOS开发数据存储篇—IOS中的几种数据存储方式 发表于2016/4/5 21:02:09  421人阅读 分类: 数据存储 在项目开发当中,我们经常会对一些数据进行本地缓存处理.离线缓存的数据一般都保存在APP所在的沙盒之中.一般有以下几种: 1.PList(XML属性列表) 在使用plist进行数据存储和读取,只适用于系统自带的一些常用类型才能用,且必须先获取路径相对麻烦 //写入文件 NSString *doc = [NSSearchPathForDirectoriesInDomains(

iOS开发笔记 - 语言篇之Swift

?2014年的苹果全球开发者大会(WWDC),当Craig Federighi向全世界宣布"We have new programming language"(我们有了新的编程语言)的时候,全场响起了最热烈和持久的掌声,伴随着掌声到来的语言叫Swift.接下来Craig Federighi更是毫不掩饰的告诉大家,Swift将成为主宰iOS和Mac开发的新语言,甚至是整个软件行业中最举足轻重的语言. ??Swift正如它的名字那样迅速.敏捷,但这并不是它的全部.Swift是一个博采众长的

ios开发——实用技术OC-Swift篇&触摸与手势识别

iOS开发学习之触摸事件和手势识别 iOS的输入事件 触摸事件 手势识别 手机摇晃 一.iOS的输入事件 触摸事件(滑动.点击) 运动事件(摇一摇.手机倾斜.行走),不需要人为参与的 远程控制事件(耳机控制手机声音) 1??iOS事件对象都是UIEvent类的实例 UIEvent类对事件类型定义了enum常量: typedef NS_ENUM(NSInteger, UIEventType){ UIEventTypeTouches, UIEventTypeMotion, UIEventRemote

【iOS开发-50】利用创建新的类实现代码封装,从而不知不觉实践一个简单的MVC实验

接上次案例谈代码封装.上次案例见:[iOS开发-48]九宫格布局案例:自动布局.字典转模型运用.id和instancetype区别.xib重复视图运用及与nib关系 代码封装的原则是:要保证视图控制器尽量少的接触到其他对象的属性,也就是说,尽量把数据或者属性封装到一个类里面,然后利用类或者对象的方法来调用或者设置数据.而是赤裸裸地把属性都写在视图控制器中.核心作用在于:减少视图控制器的代码量,把数据和属性的处理封装起来,这样也便于其他视图控制器的使用. 要做到的结果就是如下(我们要根据数组里面的

iOS开发笔记 - 网络篇

计算机网络基础 ??计算机网络是多台独立自主的计算机互联而成的系统的总称,最初建立计算机网络的目的是实现信息传递和资源共享. ??如果说计算机是第二次世界大战的产物,那么计算机网络则是美苏冷战的产物.20世纪60年代初期,美国国防部领导的ARPA提出研究一种崭新的.能够适应现代战争的.生存性很强的通信系统并藉此来应对苏联核攻击的威胁,这个决定促使了分组交换网的诞生,也奠定今天计算机网络的原型,这是计算机网络发展史上第一个里程碑式的事件. ??第二个里程碑式的事件是20世纪80年代初,国际标准化组