【引】objective-c,6:Autorelease Pool

时间:2024-08-05 10:04:38

参考博客:

http://blog.leichunfeng.com/blog/2015/05/31/objective-c-autorelease-pool-implementation-principle/

这一块和内存管理相关,只有理解了 autorelease 的原理,我们才算是真正了解了 Objective-C 的内存管理机制。

这里最重要的一点,是要理解一个autoreleased对象被alloc出来,其引用计数就是1。尽管没有其他对其强持有,也不会立即释放(之前说一个__weak一出来就会被释放的想方法,是错误的),而是在当前的autoreleased pool 干涸后,才会被释放。换句话说,出了所在AutoPool,其引用计数减1,引用计数为0,对象被释放。

通过这段测试代码就非常好理解:

【引】objective-c,6:Autorelease Pool

输出为:

【引】objective-c,6:Autorelease Pool

解释:

1,string是被加到当前最近的autorelease pool的,这个pool会在viewwillappear和viewdidappear中间被调用。所以,在viewwillappear,[nsstring ]对象的引用计数为1,没被释放,stirng_weak_不为nil。

2,把当前变量手动添加到一个自创的autorelease pool中。那出了这个autorelease pool,局部变量string被回收,[nsstring ]对象引用计数减1。同时autorelease 对象[nsstring ]引用计数减1,为0,被释放。所以string_weak_打印是nil。

3,这种情况,出了autorelease pool,对象的引用计数减少1。但是string依旧持有该对象,所以并没有被释放。当viewwillappear函数结束,string指针被回收,[nsstring ]对象引用计数为0,被释放。

关于NSThread,NSRunloop,NSAutoreleasePool

每一个线程,包括主线程,都会拥有一个专属的 NSRunLoop 对象,并且会在有需要的时候自动创建。(每个线程都会维护自己的 autoreleasepool)。

在系统级的线程,比如通过 dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) 获取到的线程,都会在每个event loop开始前,系统自动创建一个 autoreleasepool ,并在 event loop 结束时 drain 。比如场景1,autoreleasepool在viewwillAppear和viewdidappear中drain。