iOS 底层学习

126 阅读2分钟

1 、一个NSObject对象占用多少内存? 

  • 系统分配了16个字节给NSObject对象(通过malloc_size函数获得) 但NSObject对象内
  • 只使用了8个字节的空间(64bit环境下,可以通过class_getInstanceSize函数获得)

struct Person_IMPL {

**        struct** NSObject_IMPL NSObject_IVARS; // 8

**        int** _age; // 4

}; // 16 内存对齐:结构体的大小必须是最大成员大小的倍数

//-----------------------------------------------------------

 1.Class objc_getClass(const char *aClassName)

1> 传入字符串类名

2> 返回对应的类对象

//-----------------------------------------------------------

2.Class object_getClass(id obj)

1> 传入的obj可能是instance对象、class对象、meta-class对象

2> 返回值

a) 如果是instance对象,返回class对象

b) 如果是class对象,返回meta-class对象

c) 如果是meta-class对象,返回NSObject(基类)的meta-class对象

**2、对象的isa指针指向哪里? **

  • instance对象的isa指向class对象 
  • class对象的isa指向meta-class对象
  • meta-class对象的isa指向基类的meta-class对象

3、OC的类信息存放在哪里?

  • 对象方法、属性、成员变量、协议信息,存放在class对象中
  • 类方法,存放在meta-class对象中 
  • 成员变量的具体值,存放在instance对象 

**4、iOS用什么方式实现对一个对象的KVO?(KVO的本质是什么?) **

  • 利用RuntimeAPI动态生成一个子类,并且让instance对象的isa指向这个全新的子类 
  • 当修改instance对象的属性时,会调用Foundation的_NSSetXXXValueAndNotify函数    
  • willChangeValueForKey:
  • 父类原来的setter
  • didChangeValueForKey:

**5、如何手动触发KVO? **

  • 手动调用willChangeValueForKey:和didChangeValueForKey

**6、直接修改成员变量会触发KVO么? **

  • 不会触发KVO 

**7、通过KVC修改属性会触发KVO么? **

  • 会触发KVO

8、KVC的赋值和取值过程是怎样的?原理是什么?

**9、Category的使用场合是什么? Category的实现原理 **

  • Category编译之后的底层结构是struct category_t,里面存储着分类的对象方法、类方法、属性、协议信息 
  • 在程序运行的时候,runtime会将Category的数据,合并到类信息中(类对象、元类对象中)
  • Category和Class Extension的区别是什么?
  1. Class Extension在编译的时候,它的数据就已经包含在类信息中
  2. Category是在运行时,才会将数据合并到类信息中

10、2个容易混淆的函数

创建一个实例对象,至少需要多少内存? 

#import <objc/runtime.h> 

class_getInstanceSize([NSObject class]); 

创建一个实例对象,实际上分配了多少内存?

 #import <malloc/malloc.h> 

malloc_size((__bridge const void *)obj)

11、动态添加属性 的key

void objc_setAssociatedObject(id object, const void * key, id value, objc_AssociationPolicy policy)