ios 你必须了解的系统定义宏使用

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 15.0px Menlo; color: #78492a }
span.s1 { }

1. UNAVAILABLE_ATTRIBUTE __attribute__((unavailable))

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 15.0px Menlo; color: #78492a }
span.s1 { }

- (instancetype)init UNAVAILABLE_ATTRIBUTE;

告诉编译器该方法不可用,如果强行调用编译器会提示错误。比如某个类在构造的时候不想直接通过init来初始化,只能通过特定的初始化方法()比如单例,就可以将init方法标记为unavailable;

效果如下:

调用了会有警告

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 15.0px Menlo; color: #78492a }
span.s1 { }

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指针。

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 15.0px Menlo; color: #78492a }
span.s1 { }

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;
}

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 15.0px Menlo; color: #78492a }
span.s1 { }

时间: 2024-10-07 20:48:33

ios 你必须了解的系统定义宏使用的相关文章

iOS开发分分钟搞定C语言 —— 宏定义和关键字

一.宏定义 概念:宏定义实质是一个预编译指令,在程序未运行之前将某些指令付给相应的变量.一般情况预处理指令都是以#号开头的,所以宏定义也是以#开发,关键字为#define(定义宏定义),#undef(结束宏定义). 定义格式及作用域 一般宏定义都定义在程序的首段: #define 宏名 值. 宏定义的作用域:从开始定义的那行起,一直到文件末尾,虽然默认情况下宏定义的作用域是从定义的那一行开始, 一直到文件末尾.但是我们也可以通过对应的关键字#under提前结束宏定义的作用域. 宏定义规范 一般情

预定义宏,C语言预定义的宏详解

1.预定义宏 对于预定义宏,相信大家并不陌生.为了方便处理一些有用的信息,预处理器定义了一些预处理标识符,也就是预定义宏.预定义宏的名称都是以"__"(两条下划线)开头和结尾的,如果宏名是由两个单词组成,那么中间以"_"(一条下划线)进行连接.并且,宏名称一般都由大写字符组成. 在日常项目编程中,预定义宏尤其对多目标平台代码的编写通常具有重大意义. 通过预定义宏,程序员使用"#ifdef"与"#endif"等预处理指令,就可使

makefile 中定义宏位置需要注意一下

1 CUR_DIR = $(shell pwd) 2 3 CFLAGS = -g -Wall 4 GCC = gcc 5 GXX = g++ 6 7 TARGET = exe.out 8 9 SRC_FILES += $(shell find $(CUR_DIR) -name *.cc) 10 += $(shell find $(CUR_DIR) -name *.cpp) 11 12 OBJS = fatal-impl.o log.o 13 14 INCLUDE += -I. 15 RM = r

Yii2中系统定义的常用路径别名,如果获取web的url

下面这些别名都是在Yii2里面系统定义的,可以直接拿来就用 '@yii' => '@yii/swiftmailer' => string 'C:\wamp\www\advanced\vendor/yiisoft/yii2-swiftmailer' (length=52) '@yii/gii' => string 'C:\wamp\www\advanced\vendor/yiisoft/yii2-gii' (length=44) '@yii/faker' => string 'C:\

用freemarker定义宏实现自定义公用控件

参考文章: Freemarker自定义标签的简单分析 定义一个基本的文本框:传入参数为:resourceName idName resourceVal="" idVal="" classVal="",其中resourceName ,idName为必填, resourceVal="" idVal="" classVal="" 分别为选填,其中必填都作为空间的 name,选填的都作为结果值,

定义宏

定义宏 添加预编译指令(宏) 添加一个名为Test的宏 此时这段代码是无法执行的 1 2 3 4 5 6 public void Start() { #if Test //.. you code here #endif } 使定义的宏可用 找到 Build Setting > PlayerSetting >当前平台 > Scripting Define Symbols 添加 Test 即可.

zabbix 之定义宏(9)

定义宏 级别:     全局宏:Administration --> General --> Macros     模板宏:Configuration --> Templates -->  TEMPLATE(模板名称) --> Macros     主机宏:Configuration --> Hosts --> HOST(定义的主机名) --> Macros 示例

Inside Cisco IOS Software Architecture(第一章,系统基础知识)

由于本书写于1990年代,CEF还是cisco最新的黑科技. 所以其中很多关于操作系统的内容已经不太正确.Cisco的操作系统也从最开始的IOS一种形式到后来的Linux做control plane的IOS,IOS-XR,IOS-XE,NX-OS 等等等. 我相信书中提到的很多玩意已经不再使用,或者起码有所变化,但是由于没有更新的版本的书讲新的操作系统的内部,所以还是只能从这本书上了解.从学习的角度来看,从一个比较原始的形态学习也有助于一步步理解更复杂的系统. 所以不要过分纠结书的年代和细节内容

iOS日历相关操作--读取系统日历、添加事件到系统日历

1 读取系统日历 let eventStore = EKEventStore() let tempFormatter = NSDateFormatter() tempFormatter.dateFormat = "dd.MM.yyyy HH:mm" //获取一个时间段中的日历事件 let startDate = tempFormatter.dateFromString("10.08.2016 15:10")! let endDate = tempFormatter.