当我们定义某个属性的时候  如果当前使用的编译器版本比较高(6.3+)的话经常会遇到这样一个警告:

而且奇怪的是在某些文件中定义这个属性是没有任何警告的 但是在某些文件中定义同样的属性就会报错:

其实这是由于Swift的加入引起的问题:

我们都知道在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表示对象不应该为空。当我们不遵循这一规则时,编译器就会给出警告。

如果需要每个属性或每个方法都去指定nonnull和nullable,是一件非常繁琐的事。苹果为了减轻我们的工作量,专门提供了两个宏:NS_ASSUME_NONNULL_BEGIN和NS_ASSUME_NONNULL_END。在这两个宏之间的代码,所有简单指针对象都被假定为nonnull,因此我们只需要去指定那些nullable的指针。如下代码所示:

//
// CDLabel.h
// Created by 高增洪 on
// #import <UIKit/UIKit.h>
#import "TTTAttributedLabel.h"
NS_ASSUME_NONNULL_BEGIN
@interface CDLabel : TTTAttributedLabel
@property (nonatomic,strong) NSMutableArray *nameAry;
@property (nonatomic,strong,nullable) NSMutableArray *nameAry2; - (instancetype)itemWithName:(NSString *)name;
- (nullable instancetype)itemWithName2:(nullable NSString *)name2;
NS_ASSUME_NONNULL_END
@end

在上面的代码中,nameAry属性默认是nonnull的,而nameAry2属性则是nullable  -itemWithName:方法的返回值也是nonnull,而参数是指定为nonnull的。

而inirWithName2方法返回值和参数都指定是nullable

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

  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。

参考:Nullability and Objective-C

   cocoChina

警告:Pointer is missing a nullability type specifier (__nonnull or __nullable)的更多相关文章

  1. warning:Pointer is missing a nullability type specifier (__nonnull or __nullable)

    当我们定义某个属性的时候  如果当前使用的编译器版本比较高(6.3+)的话经常会遇到这样一个警告:warning:Pointer is missing a nullability type speci ...

  2. Pointer is missing a nullability type specifier (__nonnull or __nullable)

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

  3. error C4430:missing type specifier 解决错误

    错误    3    error C4430: missing type specifier - int assumed. Note: C++ does not support default-int ...

  4. MFC中使用ATL报错:error C4430: missing type specifier - int assumed. Note: C++ does not support default-int

    我在MFC中使用ATL函数A2W的时候报如下的错误: error C4430: missing type specifier - int assumed. Note: C++ does not sup ...

  5. error C4430: missing type specifier - int assumed. Note: C++ does not support default-int 解决方法

    在VS2012中生成时出错:error C4430: missing type specifier - int assumed. Note: C++ does not support default- ...

  6. 做MFC的时候引用了头文件但VC还是报missing storage-class or type specifiers

    我在客户端clg.h头文件中引用了头文件“ClientSocket.h”,然后在客户端clg.h中的类中声明了类CClientSocket的对象,可是编译报错:d:\vc++\客户端\客户端dlg.h ...

  7. GetDocument missing storage-class or type specifiers的解决方法

    error C2143: syntax error : missing ';' before '*'error C2501: 'CTest1Doc' : missing storage-class o ...

  8. declaration specifier, declarator, type specifier

    static struct abc * b; static struct abc : declaration specifier * b : declarator struct abc : type ...

  9. error C4430: missing type specifier - int assumed. Note: C++ does not support default-int

    以前一直用的VC6.0,最近换成VS2010了.哎这几天光折腾VS2010了. 曾经我以为程序没啥头绪忒头疼,现在觉得乱七八糟的编译问题才叫一个头裂=口= 原因:VC6.0中,如果没有直接显示指定的返 ...

随机推荐

  1. HDU 1074 Doing Homework 状压DP

    由于数据量较小,直接二进制模拟全排列过程,进行DP,思路由kuangbin blog得到,膜拜斌神 #include<iostream> #include<cstdio> #i ...

  2. 解决session失效之后登陆后重新返回之前的页面

    在全局拦截器设置保存之前的url存入session中 登陆之后的地址再重session中存 request只用作一次请求 如果页面跳转几次的话原来的url就不存在了建议存在session @Overr ...

  3. IE兼容性问题解决方案4--form表单在IE下重复提交

    遇到过一种情况,点击提交按钮的时候,在IE下重复提交,而在其他浏览器下正常. 原因:button按钮不设置type时,在IE下被浏览器默认解析为type="submit",用js提 ...

  4. 对单片机的modbus RTU的详细解释(转载)

    Modbus 一个工业上常用的通讯协议.一种通讯约定.Modbus协议包括RTU.ASCII.TCP.其中MODBUS-RTU最常用,比较简单,在单片机上很容易实现.虽然RTU比较简单,但是看协议资料 ...

  5. C++ 模板类解析

    具体模板类作用这边就不细说了,下面主要是描述下模板类的使用方法以及注意的一些东西. #include <iostream> using namespace std; template &l ...

  6. 命令rm

    mv -r 递归删除文件夹内所有东西mv -i 交互式删除mv -f 强制删除,没有警告提示

  7. POJ-3714 Raid 平面最近点对

    题目链接:http://poj.org/problem?id=3714 分治算法修改该为两个点集的情况就可以了,加一个标记... //STATUS:C++_AC_2094MS_4880KB #incl ...

  8. android事件分发笔记

    1.SimpleOnGestureListener 遇到的问题: 自己定义一个按钮继承自Button,一开始改变按钮颜色的操作放在onTouchEvent的ATION_DOWN里触发. 这时问题来了, ...

  9. hdoj 2050 折线分割平面

    折线分割平面 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...

  10. 74LS164 for stm32 源码下载

      在单片机系统中, 如果并行口的IO资源不够,而串行口又没有其他的作用, 那么我们可以用74LS164来扩展并行IO口,节约单片机资源.       74LS164是一个串行输入并行输出的移位寄存器 ...