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

我们来看看以下的实例:

 @interface StudentClass ()

 @property (nonatomic, copy) NSArray *studentArray;

 - (id)studentWithName:(NSString *__nonnull)name;

 @end

 @implementation StudentClass

 - (void)testNullability {
[self studentWithName:nil];
// 编译器警告:Null passed to a callee that requires a non-null argument
} - (id)studentWithName:(NSString *__nonnull)name {
return nil;
} @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,除非是为了向后兼容。

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

  1. Swift _ OC _ 混编

    Swift _ OC _ 混编 在OC环境下使用Swift. GitHub源码

  2. 详解Swift和OC的混编

    前言: 我们在一些情况下,仅仅使用swift 是无法完成一个项目的,在swift项目中必要用到 OC 实现一些功能,比如,项目要使用一些第三方的框架,但这个第三方的框架却是用 OC 实现的,或者你的项 ...

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

    由于SDK现在大部分都是OC版本, 所以假如你是一名主要以Swift语言进行开发的开发者, 就要面临如何让OC和Swift兼容在一个工程中, 如果你没有进行过这样的操作, 会感觉异常的茫然, 不用担心 ...

  4. swift和oc的混编

    一.Swift工程中加入oc代码 1.在将oc代码加入到Swift工程的时候Xcode会自动创建一个桥接文件“yourProgectName-Bridging-Header.h”,如果没有创建或者删除 ...

  5. 开发 Swift 和 Objective-C 混编的 Framework

    来源:黄文臣 blog.csdn.net/hello_hwc/article/details/58320433 前言 为什么要写这样一篇文章,因为昨天和一个朋友讨论到Swift和Objective C ...

  6. obeject-c 与 swift 混编

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px ".PingFang SC"; color: #454545 } p.p2 ...

  7. swift实现与OC的混编

    swift与OC的混编 现在写swift,很多的类库还不是很全,很多的第三方还是只有OC版的,这个时候swift想用,通常都是采用的swift和OC混编的方式.这里给大家演示一下混编是如何做的. sw ...

  8. 详解 swift2.2 和 OC 的混编

    前言: 我们在一些情况下,仅仅使用swift 是无法完成一个项目的,在swift项目中必要用到 OC 实现一些功能,比如,项目要使用一些第三方的框架,但这个第三方的框架却是用 OC 实现的,或者你的项 ...

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

    swift 语言是苹果公司在2014年的WWDC大会上发布的全新的编程语言.Swift语言继承了C语言以及Objective-C的特性,且克服了C语言的兼容性问题.Swift语言采用安全编程模式,且引 ...

随机推荐

  1. IOS开发--C语言入门--如何结合Terminal和Vim开发C语言程序

    一直以来都想着挤出时间,记录开发之路的点点滴滴(现在记录已成回忆),和大家一起分享,开发人员总是在沟通和相互学习中提高自身的能力.路过的大神也好初学者也罢,若发现文章中又观点不对的,还望大家指出. 现 ...

  2. Cocos2d-x 3.x学习笔记(一):开始Cocos2d之旅

    首先,进入官网下载cocos2d-x:http://www.cocos.com/download/,当然你需要注册一个账号才可以下载. 接下来需要跟着官网的配置文档配置一下开发环境,不得不说,Coco ...

  3. Moebius实现Sqlserver集群~介绍篇

    今年是一个不平凡的一年,接触到了很多新艳的,让人兴奋的东西,虽然自己的牙掉了两颗,但感觉自己又年青了两岁,哈哈!进入正题,今年公司开始启用数据库集群,对于Sqlserver来说,实现方式并不是很多,一 ...

  4. SAP ABAP 处理字符串串串串串串串串(详细)

    关于ABAP中处理字符串的方法,非常详细,学习过程中总结一下分享给大家,,, ABAP/4 提供多个处理类型 C 即字符串 的数据对象的关键字. 处理字符串 的方法有: 1.拆分字符串split 2. ...

  5. HDU4279(2012年天津网络赛---数论分析题)

    题目:Number 题意: 给出一个f(x),表示不大于x的正整数里,不整除x且跟x有大于1的公约数的数的个数.定义F(x),为不大于x的正整数里,满足f(x)的值为奇数的数的个数.题目就是求这个F( ...

  6. 使用 Spring 3 MVC HttpMessageConverter 功能构建 RESTful web 服务

    原文地址:http://www.ibm.com/developerworks/cn/web/wa-restful/ 简介: Spring,构建 Java™ 平台和 Enterprise Edition ...

  7. JQuery.Ajax之错误调试帮助信息介绍

    下面是Jquery中AJAX参数详细列表: timeout Number 设置请求超时时间(毫秒).此设置将覆盖全局设置. async Boolean (默认: true) 默认设置下,所有请求均为异 ...

  8. iOS开发笔记系列-基础1(数据类型与表达式)

    学习iOS开发快两年了,去年完成MagViewer之后就因为公司的其他业务繁重,除了维护这个应用之外,只是断断续续地自己做一些实验开发,没有再发布新的应用,这里想整理一下学习过程中的笔记,以便加深印象 ...

  9. .NET分布式事务处理总结【下】 - 包含MSMQ的分布式事务处理

    转自:http://www.cnblogs.com/daxnet/archive/2011/03/15/1984995.html .NET直接提供对MSMQ的访问支持,只需要添加System.Mess ...

  10. External file changes sync may be slow: Project files cannot be watched (are they under network mount?)

    if some files are on a mounted disk: go to Settings | Notifications | File Watcher Messages and tune ...