iOS 学习笔记
一、内存分配 结构体分配内存,内存对齐(8的倍数) 对象分配内存,内存对齐(16的倍数) 一个NSObject对象占用多少内存?(一个指针变量所占用的大小(64bit,8个字节,32bit,4个字节)) class_getInstanceSize() 至少需要多少内存 malloc_size() 实际分配了多少内存 二、对象 对象类型(实例对象、类对象、元类对象) 对象的isa指针指向哪里?(instance对象的isa指向class对象;class对象的isa指向meta-class对象;meta-class对象的isa指向基类的meta-class对象) OC的类信息存放在哪里?(对象方法、属性、成员变量、协议信息,存放在class对象中;类方法存放在meta-class对象中;成员变量的具体值存放在instance对象中) isa & ISA_MASK 才是真正的类对象或元类对象地址(arm64下是0x0000000ffffffff8ULL) 三、KVO、KVC KVO的本质(利用runtime动态生成一个子类,重写set方法、class、dealloc、isKVOA方法,并且让instance对象的isa指向这个全新的子类;当修改instance对象的属性时,会调用_NSSetXXXValueAndNotify函数;willChangeValueForKey/setter/didChangeValueForKey) 如何手动触发KVO(手动调用willChangeValueForKey/didChangeValueForKey,必须两个方法都调用) 直接修改成员变量会触发KVO吗(不会) KVC set原理(查找set方法:setKey -> _setKey;查看accessInstanceVariablesDirectly;查找成员变量:_key -> _isKey -> key -> isKey) KVC get原理(查找get方法:getKey -> key -> isKey -> _key;查看accessInstanceVariablesDirectly;查找成员变量:_key -> _isKey -> key -> isKey) 四、Category Category 原理(编译成struct category_t,存储这对象方法、类方法、属性、协议信息,程序运行时会将Category的数据合并到类信息中) Category和Class Extension区别(Class Extension在编译的时候数据就包含在类信息中;Category在运行时才会将数据合并到类信息中) +load方法的调用顺序(类:先编译的先调用;先调用父类的 分类:按照编译顺序调用) +initialize方法在类第一次接收到消息时调用,先调用父类的+initialize,再调用子类的+initialize +load和+initialize最大的区别是,+load通过函数地址直接调用,+initialize通过objc_msgSend进行调用,遵循消息发送的机制(如果分类实现了+initialize,则调用分类的;如果子类没有实现,则调用父类的+initialize;父类的可能被调用多次) 五、关联对象 key的设置(@selector(key) / static const char key; &key; / static const void *key = &key / @“key") 关联对象不是存储在被关联对象本身内存中,而是存储在全局的统一的一个AssociationManager中 AssciationsManager -> AssociationHashMap -> object: ObjectAssociationMap -> key: ObjectAssociation -> policy/value 对象销毁时会把对象对应的ObjectAssociationMap销毁 六、Block 本质是结构体对象(__main_block_impl_0) block类型(NSGlobalBlock:没有访问auto变量;NSStackBlock:访问了auto变量;NSMallocBlock:NSStackBlock copy) 捕获auto变量(NSStackBlock:不会强引用auto变量,栈block随时释放,没必要强引用) NSMallocBlock:当block拷贝到堆上时,会调用desc里面的copy函数,把auto变量拷贝到堆上;当从堆上移除时,会调用desc里面的dispose函数,release auto变量 __block 修饰符,会将其修饰的变量包装成一个对象;不能修饰全局变量、静态变量 MRC下,block不会对__block修饰的对象进行强引用(MRC下,可用__block解决循环引用问题) __weak:不会产生强引用,指向的对象销毁时会自动置nil; __unsafe_unretained:不会产生强引用,不安全,指向的对象销毁时,指针存储的地址值不变 ...