2016-12-28 5 views
2

Вот программа Objective-C для OS X, которая использует ARC - вы можете построить ее с помощью cc -fobjc-arc -o objc_arc_test objc_arc_test.m или что-то в этом роде. Он создает две пары из двух объектов: одну с помощью alloc/init и одну с использованием фабричной функции (то, что вы используете autorelease для кода pre-ARC), все за пределами любого пула авторезистов, выводятся сообщения об инициализации и dealloc, поскольку он идет.Почему эти объекты ARC ведут себя непоследовательно?

#import <Foundation/NSObject.h> 
#include <stdio.h> 

#if !__has_feature(objc_arc) 
#error 
#endif 

@interface TestClass:NSObject { 
    int value; 
} 
-(TestClass *)initWithValue:(int)value; 
-(void)dealloc; 
+(TestClass *)testClassWithValue:(int)value; 
@end 

@implementation TestClass 
-(TestClass *)initWithValue:(int)value_ { 
    if((self=[super init])) 
     self->value=value_; 

    printf("init: self=%p value=%d\n",self,self->value); 
    return self; 
} 

-(void)dealloc { 
    printf("dealloc: self=%p value=%d\n",self,self->value); 
} 

+(TestClass *)testClassWithValue:(int)value { 
    return [[TestClass alloc] initWithValue:value]; 
} 

@end 

static void f() { 
    TestClass *c5=[TestClass testClassWithValue:5]; 
    TestClass *c6=[[TestClass alloc] initWithValue:6]; 
} 

static void f2() { 
    TestClass *c7=[TestClass testClassWithValue:7]; 
    TestClass *c8=[[TestClass alloc] initWithValue:8]; 
} 

int main() { 
    f(); 
    f2(); 
} 

бы я ожидал получить инициализации сообщения для 4 объектов и dealloc сообщений на 2, так как ARC обеспечит Alloc + init'd объекты разрушаются и, по причине отсутствия autorelease бассейна, будет Оставьте остальные одни.

Но что я получаю вместо этого сообщения инициализации для 4-х объектов и dealloc сообщений для 3:

init: self=0x7fea20500690 value=5 
init: self=0x7fea205006f0 value=6 
dealloc: self=0x7fea205006f0 value=6 
init: self=0x7fea205006f0 value=7 
init: self=0x7fea20500700 value=8 
dealloc: self=0x7fea20500700 value=8 
dealloc: self=0x7fea205006f0 value=7 

Я не понимаю такого поведения! Я ожидал бы, что значение = 5 и значение = 7 объектов будут вести себя одинаково.

Почему это делается?

(OS X 10.11.6, Xcode 8 - Apple LLVM version 8.0.0 (clang-800.0.38), Target: x86_64-apple-darwin15.6.0, Thread model: posix)

ответ

4

Так как я считаю, OS X 10.9, есть autorelease бассейн автоматически создается на верхнем уровне, даже если вы не делаете один (это избавило от исторического "объекта, автореализованного без пула автоопределения, просто утечки" предупреждения).

Тем не менее, это не имеет особого отношения к этой ситуации. ARC не обещает, что что-либо когда-либо будет автореализовано. Он может свободно использовать явные выпуски, когда он может доказать, что вы не будете использовать объект позже. ARC обязана гарантировать, что объекты с сильными ссылками не будут уничтожены, а объекты без сильных ссылок будут уничтожены. Autoreleasepool - это подробная информация о реализации, которую ARC может использовать или не использовать по своему усмотрению. В качестве оптимизации ARC часто избегает пула авторесурсов в тех местах, которые мы использовали бы вручную в прошлом.

Стоит также отметить, что dealloc на самом деле не обещано. Программа бесплатна для завершения без ее запуска (это масштабная оптимизация, поэтому программы ObjC могут прекращаться значительно быстрее, чем программы на C++). В этом случае это случается, но если вы полагаетесь на dealloc для запуска или не запуска, вы, вероятно, злоупотребляете им.

Смежные вопросы