首页 热点资讯 义务教育 高等教育 出国留学 考研考公
您的当前位置:首页正文

面试篇(一):内存管理你都知道哪些?

2024-12-18 来源:华拓网

引用计数器

在ObjC中内存的管理是依赖对象引用计数器来进行的,ObjC中内存的管理在ObjC中每个对象内部都有一个与之对应的整数(retainCount),叫引用计数器”,当一个对象在创建之后它的引用计数器为1,当调用这个对象的alloc、retain、new、copy方法之后引用计数器自动在原来的基础上加1(ObjC中调用一个对象的方法就是给这个对象发送一个消息),当调用这个对象的release方法之后它的引用计数器减1,如果一个对象的引用计数器为0,则系统会自动调用这个对象的dealloc方法来销毁这个对象。

自动释放池

在ObjC中也有一种内存自动释放的机制叫做自动引用计数(或“自动释放池”),与C#、Java不同的是,这只是一种半自动的机制,有些操作还是需要我们手动设置的。自动内存释放使用@autoreleasepool关键字声明一个代码块,如果一个对象在初始化时调用了autorelase方法,那么当代码块执行完之后,在块中调用过autorelease方法的对象都会自动调用一次release方法。

  • autorelease方法不会改变对象的引用计数器,只是将这个对象放到自动释放池中;

  • 自动释放池实质是当自动释放池销毁后调用对象的release方法,不一定就能销毁对象(例如如果一个对象的引用计数器>1则此时就无法销毁);

常量 和 对象?堆 ?栈?

  • 常量:会被放入栈中,他们依次紧密排列,在内存中占有一块连续的内存空间,遵循先进后出的原则。

  • 对象:会被放到堆中,当给对象分配内存空间时,会随机的从内存当中开辟空间,对象与对象之间可能会留有不确定大小的空白空间,因此会产生很多内存碎片,需要我们管理。

  • 栈内存与堆内存从性能上比较,栈内存要优于堆内存,这是因为栈遵循先进后出的原则,因此当数据量过大时,存入栈会明显的降低性能。因此,我们会把大量的数据存入堆中,然后栈中存放堆的地址,当需要调用数据时,就可以快速的通过栈内的地址找到堆中的数据。

内存管理修饰符

  • ARC
strong :强引用,ARC中使用,与MRC中retain类似,使用之后,计数器+1。

copy :表示拷贝,setter方法将传入对象复制一份,需要完全一份新的变量时。

assign :用于基本数据类型, 相当于MRC中的 assign。

weak : 用于OC对象, 相当于MRC中的 assign。

  • MRC
retain :表示持有特性,setter方法将传入参数先保留,再赋值,传入参数的retaincount会+1。

  • 其他
readwrite : 可读可写特性,需要生成getter方法和setter方法时使用。

readonly : 只读特性,只会生成getter方法 不会生成setter方法,不希望属性在类外改变。

nonatomic :非原子操作,不加同步,多线程访问可提高性能,但是线程不安全的。

atomic :原子操作,同步的,表示多线程安全,与nonatomic相反。

  • strong 和 copy 的区别?
#import "ViewController.h"

@interface ViewController ()

@property (nonatomic, strong) NSString *mStrongString;

@property (nonatomic, copy) NSString *mCopyString;

@end

@implementation ViewController

- (void)viewDidLoad {
    
    [super viewDidLoad];
    // mStrongString 和 mCopyString 的指针指向了mStr。
    // 当mStr 的值改变的时候,mStrongString 会随之改变。
    // mCopyString 的值不会随着改变。
    
    NSMutableString *mStr = [NSMutableString stringWithString:@"hello"];
    
    self.mStrongString = mStr;
    self.mCopyString = mStr;
    
    [mStr appendString:@"word"];
    NSLog(@"theStrongName = %@, theCopyName = %@", 
    self.mStrongString, self.mCopyString);
    
}

输出结果:2016-12-21 13:52:35.678 L[30705:2526456] 
theStrongName = helloword, theCopyName = hello

  • strong 和 weak 的区别?

这篇文章可以很好的理解~~原理也很清晰

显示全文