1.__autoreleasing 作用是將對象添加到最近的@autoreleasepool中,當@autoreleasepool出作用域時候會釋放其中的對象。
2.釋放順序是先進后出
3.__autoreleasing 會獲取當前的hotpage 如果沒有則會創建一個AutoreleasePage作為hotpage。
4.默認系統級別的runloop都會添加observe,每次runloop啟動之后即將工作和即將進入休眠模式的時候分別會創建和銷毀AutoreleasePool。并且,創建時候級別最高,以保證其runloop中所有的操作都在Pool之后,釋放的時候級別最低,以保證所有其他的任務進行。
5.子線程中不會自動創建AutoreleasePool以及runloop。
6.AutoreleasePage 其實是個雙向鏈表。以保證能先查找child再查找parent。
7.當AutoreleasePage嵌套時候,其實是插入哨兵對象,每一次push就插入一個哨兵對象,當pop的時候就從當前的next開始查找找到最后插入的一個哨兵對象,都統一發送release操作。然后修改next到正確的位置
//1.
dispatch_queue_t queut = dispatch_queue_create("myname", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queut, ^{
Person *p = [Person new];
NSLog(@"1,%p",p);
@autoreleasepool {
Person *p1 = [[Person alloc] init];
NSLog(@"2,%p",p1);
}
Person *p3 = [[Person alloc] init];
NSLog(@"3,%p",p3);
});
//2.
dispatch_queue_t queut = dispatch_queue_create("myname", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queut, ^{
Person *p = [Person new];
NSLog(@"1,%p",p);
__autoreleasing Person *p1 = [[Person alloc] init];
NSLog(@"2,%p",p1);
Person *p3 = [[Person alloc] init];
NSLog(@"3,%p",p3);
});
這段代碼注意 1和2釋放順序是不一樣的。
- (void)testMethod{
NSLog(@"%s",__func__);
Person *p = [Person new];
NSLog(@"1,%p",p);
Person __autoreleasing *p2 = [[Person alloc] init];
NSLog(@"2,%p",p2);
__autoreleasing Person *p3 = [[Person alloc] init];
NSLog(@"3,%p",p3);
}
上面p1因為是局部變量,出了方法作用域就釋放了,p2,p3先后加入autoreleasepool,最后釋放的時候順序是p3-p2。
如下代碼:
@interface Man : Person
@end
@implementation Man
+ (void)load{
NSLog(@"%s",__func__);
}
+(void)initialize{
NSLog(@"%s",__func__);
}
- (void)dealloc{
NSLog(@"%s,%p",__func__,self);
}
- (void)testMethod{
NSLog(@"%s",__func__);
Person *p = [Person new];
NSLog(@"1,%p",p);
Person __autoreleasing *p2 = [[Person alloc] init];
NSLog(@"2,%p",p2);
__autoreleasing Person *p3 = [[Person alloc] init];
NSLog(@"3,%p",p3);
}
- (void)testMethod2{
NSLog(@"%s",__func__);
Person *p = [Person new];
NSLog(@"1,%p",p);
Person __autoreleasing *p2 = [[Person alloc] init];
NSLog(@"2,%p",p2);
__autoreleasing Person *p3 = [[Person alloc] init];
NSLog(@"3,%p",p3);
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
Man *man = [[Man alloc] init];
NSLog(@"man %p",man);
[man testMethod];
[man testMethod2];
Man *man2 = [[Man alloc] init];
NSLog(@"man2 %p",man2);
NSLog(@"end autoreleasepool");
}
return 0;
}
添加順序是man -> testMethod中的p2,p3 -> testMethod2中的p2,p3 -> man2。
釋放順序是man2 -> man -> testMethod2中的p3,p2 -> testMethod中的p3,p2
http://www.lxweimin.com/p/a2999d7728b4