ios 你必须了解的系统定义宏使用
1. UNAVAILABLE_ATTRIBUTE __attribute__((unavailable))
- (instancetype)init UNAVAILABLE_ATTRIBUTE;
告诉编译器该方法不可用,如果强行调用编译器会提示错误。比如某个类在构造的时候不想直接通过init来初始化,只能通过特定的初始化方法()比如单例,就可以将init方法标记为unavailable;
效果如下:

调用了会有警告

2. NS_ASSUME_NONNULL_BEGIN , NS_ASSUME_NONNULL_END
如果需要每个属性或每个方法都去指定nonnull和nullable,是一件非常繁琐的事。苹果为了减轻我们的工作量,专门提供了两个宏:NS_ASSUME_NONNULL_BEGIN和NS_ASSUME_NONNULL_END。在这两个宏之间的代码,所有简单指针对象都被假定为nonnull,因此我们只需要去指定那些nullable的指针
- nonnull作用:不能为空
使用方法
NS_ASSUME_NONNULL_BEGIN
@interface TestNullabilityClass () @property (nonatomic, copy) NSArray * items; - (id)itemWithName:(nullable NSString *)name; @end
NS_ASSUME_NONNULL_END
在上面的代码中,items属性默认是nonnull的,itemWithName:方法的返回值也是nonnull,而参数是指定为nullable的。
不过,为了安全起见,苹果还制定了几条规则:
- typedef定义的类型的nullability特性通常依赖于上下文,即使是在Audited Regions中,也不能假定它为nonnull。
- 复杂的指针类型(如id *)必须显示去指定是nonnull还是nullable。例如,指定一个指向nullable对象的nonnull指针,可以使用”__nullable id * __nonnull”。
- 我们经常使用的NSError **通常是被假定为一个指向nullable NSError对象的nullable指针。
3. NS_DESIGNATED_INITIALIZER
Objective-C 中主要通过NS_DESIGNATED_INITIALIZER宏来实现指定构造器的。这里之所以要用这个宏,往往是想告诉调用者要用这个方法去初始化(构造)类对象。
#define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) - (instancetype)init;
- (instancetype)initWithName:(NSString *)name NS_DESIGNATED_INITIALIZER;
/*
init是 convenience initializer方法只是简单的调用initWithName:(指定初始化器),并设置一个默认值。initWithName:进行完整的初始化并调用父类的init方法。
指定初始化器有以下几个规则:
1.指定初始化器方法必须调用父类的指定初始化器方法,如果父类为NSObject时调用
[super init]。
2.convenience initializer方法必须调用其他的初始化方法,知道最后指向指定初始化
器方法。
3.一个类如果有指定初始化器方法,那么就必须实现所有父类的指定初始化器方法。
*/
- (instancetype)init {
return [self initWithName:@"Unknown"];
}
- (instancetype)initWithName:(NSString *)name {
self = [super init];
if (self) {
_name = [name copy];
}
return self;
}
ios 你必须了解的系统定义宏使用的更多相关文章
- 预定义宏,C语言预定义的宏详解
1.预定义宏 对于预定义宏,相信大家并不陌生.为了方便处理一些有用的信息,预处理器定义了一些预处理标识符,也就是预定义宏.预定义宏的名称都是以"__"(两条下划线)开头和结尾的,如 ...
- C预定义宏
作用:对于__FILE__,__LINE__,__func__这样的宏,在调试程序时是很有用的,因为你可以很容易的知道程序运行到了哪个文件的那一行,是哪个函数. 下面一个例子是打印上面这些预定义的宏的 ...
- Yii2中系统定义的常用路径别名,如果获取web的url
下面这些别名都是在Yii2里面系统定义的,可以直接拿来就用 '@yii' => '@yii/swiftmailer' => string 'C:\wamp\www\advanced\ven ...
- latex如何定义宏,插图统一尺寸减少工作量
问题背景是这样的,因为我要在文中插入一系列的图片,但是这些图片的大小我要保持一致,来达到预期的效果. 比如我有三个figure,这三个figure中,每个figure里面有两行,5列图片,我想要的是, ...
- Windows Phone 修改系统定义的资源颜色
[问题的背景] 相信有些经验的WP研发同学都会遇到下面的问题: 系统控件以及WPToolkit中大量使用了PhoneAccentBrush这个画刷(这个画刷定义的是系统的强调色,即用户选择的主题颜色) ...
- iOS:App 内部更改使用语言/ 重定义系统的宏
代码部分 #undef NSLocalizedString #define NSLocalizedString(key, comment) \ NSLocalizedStringFromTable(k ...
- iOS --- 总结Objective-C中经常使用的宏定义(持续更新中)
将iOS开发中经常使用的宏定义整理例如以下,仅包括Objective-C. 而对于Swift,不能使用宏,则能够定义全局函数或者extension.请參考博客iOS - 总结Swift中经常使用的全局 ...
- iOS开发小技巧--定义宏和pch文件的使用
一.创建pch文件,默认跟项目同名 二.告诉系统,编译的时候要编译pch文件的步骤 三.把经常用到的宏 或者 分类 包含到这里
- 查看linux系统某宏的定义(另类)
有一次我想查看time_t类型的定义,一开始想直接在/usr/include/time.h中查找,结果里面没有,而是转到另外一个:__time_t(2个下划线), 结果又转到:__STD_TYPE _ ...
随机推荐
- POJ - 3468A Simple Problem with Integers (线段树区间更新,区间查询和)
You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of op ...
- HDU - 1166 敌兵布阵 方法一:(线段树+单点修改,区间查询和) 方法二:利用树状数组
C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务就是要监视这些工兵营地的活动情况.由于 ...
- (原创)Codeforces Round #550 (Div. 3) A Diverse Strings
A. Diverse Strings time limit per test 1 second memory limit per test 256 megabytes input standard i ...
- MongoDB入门,安装配置与基本CURD操作
MongoDB特点 MongoDB是NoSQL的一种,非关系型数据库,或者叫不只是关系型数据库(Not Only SQL).MongoDB采用json格式的文档存储,与Redis的key-value有 ...
- Java异常处理方式
前言 平时在开发的时候避免不了的出一些大大小小的不同类型的错误,这时候,对于这些异常怎么处理呢,显得至关重要了. 内容 分类 Trowable:有两个重要的子类,Exception(异常)和Error ...
- New Distinct Substrings(后缀数组)
New Distinct Substrings(后缀数组) 给定一个字符串,求不相同的子串的个数.\(n<=50005\). 显然,任何一个子串一定是后缀上的前缀.先(按套路)把后缀排好序,对于 ...
- uoj#422. 【集训队作业2018】小Z的礼物(MIn-Max容斥+插头dp)
题面 传送门 题解 好迷-- 很明显它让我们求的是\(Max(S)\),我们用\(Min-Max\)容斥,因为\(Min(S)\)是很好求的,只要用方案数除以总方案数算出概率,再求出倒数就是期望了 然 ...
- 《C++标准程序库》-1
explicit关键字 这个关键字原则上只对构造函数起作用,抑制阴性转换,例如: class String{ String(int size); //本意是要申请size大小的字符串 }; 如果此时调 ...
- 2、OpenCV Python 图像属性获取
__author__ = "WSX" import cv2 as cv import numpy as np image = cv.imread("1.JPG" ...
- select和epoll原理和区别
对于select和poll,其主要原理跟epoll不同 poll和select的共同点就是,对全部指定设备(fd)都做一次poll,当然这往往都是还没有就绪的,那就会通过回调函数把当前进程注册到设备的 ...