面试

KVC

KVC可以通过key直接访问对象的属性,或者给对象的属性赋值(包括私有属性),这样可以在运行时动态的访问或修改对象的属性。

setValue forKey
Person *person = [[Person alloc] init];
[person setValue:@"小明" forKey:@"userName"];
NSString *name = [person getPrivateName];
NSLog(@"person private name:%@",name);
  • 首先要调用对象的setter方法。
  • 如果没有找到对应的属性,会找相应的_name成员变量。
  • 如果还是没有找到,会执行- (void)setValue:(id)value forUndefinedKey:(NSString *)key方法。可以在方法里做相应的属性名转换。如果没有实现此方法,则会异常崩溃。
  • 如果想禁用KVC,+ (BOOL)accessInstanceVariablesDirectly中返回NO,默认是返回YES
valueForKey
  • 首先要调用对象的getter方法。
  • 如果没有找到,会执行- (id)valueForUndefinedKey:(NSString *)key,在此方法里可以进行处理。如果没有实现此方法,则会异常崩溃。
  • 如果想禁用KVC,+ (BOOL)accessInstanceVariablesDirectly中返回NO,默认是返回YES
setValue:forKeyPath,valueForKeyPath

valueForKeyPath的值是一个路径(路径之间以点号 . 分割),比如数据成员就是对象自己,寻值过程就会向下深入下去。

autoreleasepool

main函数中的autoreleasepool从技术上看是非必要的,去掉没有什么关系。但为了严谨,为了让UIApplication创建出来的自动释放的对象有自动释放池可添加,而不是依赖程序结束后的内存回收。
APP启动的时候会在主线程注册两个observer,一个监听即将进入runloop事件,一个监听runloop即将休眠和即将退出两个事件,在runloop即将休眠和即将退出的时候会销毁@autoreleasepool{}释放自动释放池,并释放autorelease对象。

实现方式

当自动释放池创建的时候,会调用objc_autoreleasePoolPush方法,将POOL_SENTINEL(哨兵对象)放入到栈顶。随后自动释放池内的对象会被加到栈顶中。
当自动释放池释放的时候,会调用objc_autoreleasePoolPop方法,向自动释放池中的对象释放release方法,直到POOL_SENTINEL(哨兵对象)。

POOL_SENTINEL 只是 nil 的别名。

autoreleasepool是由多个autoreleasePoolPage以双向链表的形式链接起来的,当一个表满了,会自动创建下一个表,并双向链接起来。释放的时候,从最下面依次向上pop,调用每个对象的release,直到遇到标志位(POOL_SENTINEL)。

结构

autoreleasepool实际上是一个结构体,结构如下

class AutoreleasePoolPage {
    magic_t const magic;    //AutoreleasePoolPage 完整性校验
    id *next;                             //下一个存放autorelease对象的地址
    pthread_t const thread; //所在线程
    AutoreleasePoolPage * const parent;  //父节点 (双向)
    AutoreleasePoolPage *child;                 //子节点 (双向)
    uint32_t const depth;
    uint32_t hiwat;
};

内省(Introspection)

内省是面向对象语言和环境的一种特性,是在运行时(Run time)检查对象(object)的一种能力。可以通过内省,来判断对象在继承树上的位置,是否遵循特定的协议,是否可以响应特定的消息。
优点:
内省可以使面向对象程序更强壮高效,避免进行错误的消息派发,错误的假设对象。
最常见应用:

if (self.delegate && [self.delegate respondsToSelector:@selector(segmentDidChanged:)]) {
        [self.delegate segmentDidChanged:type];
 }
常用的几个内省方法:
  • isMemberOfClass : 对象是否是某个类的对象。
  • isKindOfClass : 对象是否是某个类或者某个类子类的对象。
  • isSubclassOfClass : 某个类是否是另一个类的子类。
  • respondsToSelector : 是否能响应某个方法。
  • conformsToProtocol : 是否遵循某个协议。
class方法和object_getClass方法区别
  • 实例的class方法就是直接返回object_getClass(self)
  • 类的class方法直接返回self
  • object_getClass(类)方法则返回元类。

Dealloc

http://events.jianshu.io/p/b25f50d852f2

你可能感兴趣的:(面试)