内存
-
Objective-C 如何对内存管理的,说说你的看法和解决方法?
Objective-C的内存管理主要有三种方式ARC(自动内存计数)、手动内存计数、内存池。
1). 自动内存计数ARC:由Xcode自动在App编译阶段,在代码中添加内存管理代码。
2). 手动内存计数MRC:遵循内存谁申请、谁释放;谁添加,谁释放的原则。
3). 内存释放池Release Pool:把需要释放的内存统一放在一个池子中,当池子被抽干后(drain),池子中所有的内存空间也被自动释放掉。内存池的释放操作分为自动和手动。自动释放受runloop机制影响。
-
堆和栈的区别?
栈(Stack):当我们创建一个值类型,如结构体,系统将其存储在一个被称为栈的内存区域中,是由CPU直接管理和优化的。当一个函数声明一个变量,变量将存储在栈中,当函数调用完毕后栈会自动释放该变量。因此栈是非常易于管理的、有效的,由于是CPU直接控制,速度非常快。
堆(Heap):当我们创建了一个引用类型,如类,系统将把类实例存储在一个被称为堆的内存区域中。系统使用堆来存储其他对象引用的数据。堆是一个大的内存池,系统可以从该池中请求并动态分配内存块。堆不会像栈一样自动释放对象,需要额外的工作来完成。这使得在堆中创建和删除数据比栈慢。
运行时
-
当建立一个A类,创建它的分类A+,在A类中有一个方法
- (void)test;
,在分类A+中也有一个方法- (void)test;
,在初始化A类的实例对象中,调用test
方法,会调用哪个test
方法?为什么?
解析
:会调用分类A+中的test
方法,这是因为分类在添加到类的方法列表中,我们方法列表会移动,腾出存储空间给分类添加到前面的地址空间。当调用这个方法时若分类有这个方法直接调用,它就不会再到原类中在去代调用这个方法。
-
[super class] 和 [self class] 的异同?
这里是大神针对[super class]和[self class]详细介绍。
解析: 当我们进行方法调用时,编译器会对_msgSend(其他的消息普通的用这个)、objc_msgSend_stret(结构体方法调用)、objc_msgSendSuper(message对一个类的supperClass发送消息时调用)、objc_msgSendSuper_stret(结构体方法调用)
这几个方法中调用其中一个。
[super class] 底层会调用 objc_msgSendSuper()给父类发送消息。
[super class] 最终编译器转化成了 objc_msgSendSuper(struct objc_super *,SEL) ,其中
struct objc_super {
/// Specifies an instance of a class.
__unsafe_unretained _Nonnull id receiver;
/// Specifies the particular superclass of the instance to message.
#if !defined(__cplusplus) && !__OBJC2__
/* For compatibility with old objc-runtime.h header */
__unsafe_unretained _Nonnull Class class;
#else
__unsafe_unretained _Nonnull Class super_class;
#endif
/* super_class is the first class to search */
};
objc_super
是一个结构体,内部有一个 receiver 实例,和一 个 Class super_class,指向了当前类的父类 Class ,通过这个父类可以直接的从父类里边开始查找方法,由于消息接收者还是当前类的实例对象 self, 最终如果在父类中没有找到class 这个方法,会在 Person 类的父类 NSObject 中去查找 class 方法,由于 NSObject 的 class 方法,调用的是 object_getClass(self) ,所以最终消息接收者为 student 实例对象,所以返回的还是 Student .
[self class] 在调用 class 方法时最终会调用这个方法并且返回值:
//在NSObject.mm文件中的NSObject类定义的方法中
Class object_getClass(id obj)
{
if (obj) return obj->getIsa(); //返回当前对象的isa
else return Nil;
}
当我们调用[self class] 时候实际上编译器最终给我们转成 objc_msgSend(self,@selector(class))
, 消息的接收者是当前所在类的实例对象 , 这个时候就会去 self 所在类 Student 去查找 class 方法 , 如果当前类 Student 没有 class 会向Student 父类 Person 类找 class 方法, 如果 Person 类也没有找到 class 方法,最终会找到最顶级父类 NSObject 的 class 方法, 最终找到 NSObject 的 class 方法 ,并调用了object_getClass(self) ,由于消息接收者是 self 当前类实例对象, 所以最终 [self class]输出 Student。
1. Objective-C 如何对内存管理的,说说你的看法和解决方法?
答:Objective-C的内存管理主要有三种方式ARC(自动内存计数)、手动内存计数、内存池。
1). 自动内存计数ARC:由Xcode自动在App编译阶段,在代码中添加内存管理代码。
2). 手动内存计数MRC:遵循内存谁申请、谁释放;谁添加,谁释放的原则。
3). 内存释放池Release Pool:把需要释放的内存统一放在一个池子中,当池子被抽干后(drain),池子中所有的内存空间也被自动释放掉。内存池的释放操作分为自动和手动。自动释放受runloop机制影响。
``