说到Objc运行时,若是你还不清楚,那可要看仔细了,若是你是靠颜值而不是才华可以顺利经过面试,喵了个咪的,我也想去试试html
iOS出现时就是运行时2.0版本了,和旧的相比拥有两大特性:
第一,就是修改,增长或删除一个类的实例变量,不用再从新编译子类就能够用了。
第二,就是加为@property加入了Synthesizeios
请将属性property(atomic,nonatomic, assign, weak, strong, copy, readonly, readwrite blah!blah!)按照功能分组git
请回答下列@property变量cool和cat的默认属性github
@interface ViewController : UIViewController @property BOOL cool; @property NSObject *cat; @end
Objc运行时至关于Objective-C的操做系统,当咱们编译代码时,编译器把源码编译成运行时可以懂得数据结构(好比isa包括类的继承信息)和运行时方法(好比objc_msgSend), 剩下的就交给运行时动态处理了。面试
@interface NSObject{ objc_class *isa } //点开isa连接搜索struct objc_class : objc_object可以查到其声明 struct objc_class : objc_object { // Class ISA; objc_class *superclass; .... 方法派遣表 selector对应的C语言函数 .... } 从objc_class声明能够看出,每个isa->superclass一样是objc_class类型, 这样就组成了一个继承的链表结构
1.写Objective-C代码必然用到,虽然没这种感受
2.调用NSObject运行时方法
3.直接调用运行时API缓存
objc方法只不过是C语言方方法,加上两个特殊的参数第一个是receiver(self),第二个参数是selector(_cmd)数据结构
好比如下的方法调用 [receiver message:arg1] //假设定义arg1为BOOL类型
具体实现: (void (*)(id, SEL, BOOL))[target methodForSelector:@selector(message:)];
运行时:app
`objc_msgSend(receiver, selector, arg1)`
objc_msgSend作的事情以下:ide
根据receiver和selector先在receiver的方法派遣表里面查找是否有selector这个方法实现, 若是没找到,receiver->isa->superclass去查找,以此类推,直到找到对应的方法实现,若直到NSObject都没有找到对应实现,中间过程在下文解释,最后掉用[receiver doesNotRecognizeSelector:_cmd]
就抛异常出错了函数
将全部参数传给具体实现方法调用
将具体实现结果反回来
尽管objc_msgSend在成功调用一次方法以后,每一个Class会有缓存,下次重复调用该方法时,查找速度会大大提升,可是仍是有运行时消息发送的时间,若是一个函数被调用成千上万次,为了减小消息派遣时间,能够跳过运行时objc_msgSend,直接调用方法实现
void (*message)(id, SEL, BOOL); int i; message = (void (*)(id, SEL, BOOL))[target methodForSelector:@selector(message:)]; for ( i = 0 ; i < 1000 ; i++ ) setter(targetList[i], @selector(message:), YES);
原子性:atomic,nonatomic
读写性: readwrite, readonly
ARC版内存管理: assign, strong, copy, weak
@property cool = TB,V_cool @property cat = T@"NSObject",&,V_cat
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. id LenderClass = objc_getClass("ViewController"); unsigned int outCount, i; objc_property_t *properties = class_copyPropertyList(LenderClass, &outCount); for (i = 0; i < outCount; i++) { objc_property_t property = properties[i]; fprintf(stdout, "@property %s = %s\n", property_getName(property), property_getAttributes(property)); } }
子问题2: 如何解读?首先说明这奇怪的字符时编译器干的好事啦,参考主要是这里还有这里
The string returned by |property_getAttributes| starts with a T followed by the @encode type and a comma, and finishes with a V followed by the name of the backing instance variable.
上面一坨就是说,property_getAttributes得到的字符串的格式,以T开头,而后是<变量类型>,而后是一个逗号,而后是<属性>,最后是一个V,再日后就是下划线_和变量名了
/*根据文档: 若是是readonly应该有R属性, 因此默认应该是readwrite 若是是weak,strong,copy应该分别有W, &, C, 因此默认应该是assign 若果有nonatomic应该有N, 因此默认是atomic TB,V_cool B表明BOOL, 中间什么属性都没有对不对,根据以上分析,默认是atomic, assign, readwrite T@"NSObject",&,V_cat 则是atomic, strong, readwrite */