一.NSObject+YYModel.h
NS_ASSUME_NONNULL_BEGIN和NS_ASSUME_NONNULL_END
打开NSObject+YYModel.h
,会看到NS_ASSUME_NONNULL_BEGIN
和NS_ASSUME_NONNULL_END
说明下: 如果需要每个属性或每个方法都去指定nonnull和nullable,是一件非常繁琐的事。苹果为了减轻我们的工作量,专门提供了两个宏:NS_ASSUME_NONNULL_BEGIN和NS_ASSUME_NONNULL_END。在这两个宏之间的代码,所有简单指针对象都被假定为nonnull,因此我们只需要去指定那些nullable的指针。
1.nil Nil NULL NSNull kCFNull的区别
- nil代表指向一个实例对象的空指针
NSString *msg = nil;
- Nil表示指向一个类的空指针:
Class class = Nil;
- NULL 定义其他类型(基本类型、c类型)的空指针
char *p = NULL;
NSNull 表示数组中的占位符,数组中的元素不能为nil, nil代表数组结束的标志, 所以为空的话可以用NSNull来占位
kCFNull : NSNull的单例
CF_EXPORT 就是 extern
(2)force_inline
define force_inline inline attribute((always_inline))
这行代码用到了C语言的内联函数
*内联函数: 是用inline修饰的函数,内联函数在代码层次看和普通的函数结构一样,却不具备函数的性质,内联函数不是在调用时发生控制转移,而是在编译时将函数体嵌入到调用处,和宏很类似,但是有一下不同点. 他们之间的区别在于: 宏是由预处理器进行替代的,而内联函数则是通过编译器控制实现的,内联函数是真正的函数,只有在需要用到的时候才会像宏那样的展开,所以取消了函数的参数压栈,减少了调用的开销,我们可以像调用函数一样调用内联函数,而不必担心产生于处理宏一样的问题.
*__inline
与inline
等同。inline
和__inline
通知编译器将该函数的内容拷贝一份放在调用函数的地方,这称之为内联。内联减少了函数调用的开销,但却增加了代码量. __attribute__((always_inline))
的意思是强制内联,所有加了__attribute__((always_inline))
的函数再被调用时不会被编译成函数调用而是直接扩展到调用函数体内.
(3)block有三种形式的: NSStackBlock, NSGlobalBlock, NSMallocBlock.
*NSStackBlock表示在block内部引用外部变量的, NSGlobalBlock表示在block内部没有引用外部变量的, NSMallocBlock表示堆block,MRC下引用外部变量的需要手动copy到堆上,ARC下系统自动copy.
*block在ARC下也是有NSStackBlock的block的,只是当赋值给strong对象时,系统会主动对其进行copy.