2016-12-28 9 views
2

ここでは、ARCを使用するOS X向けのObjective-Cプログラムです。cc -fobjc-arc -o objc_arc_test objc_arc_test.mなどで構築できます。これは、alloc/initを使用するオブジェクトと、ファクトリ関数を使用するオブジェクトの2つのペアを作成します(pre-ARCコードではautoreleaseを使用します)。すべての自動解放プールの外側にあり、initおよびdeallocメッセージをそのまま出力します行く。私はARCは、アロケーションを保証します+ init'dオブジェクトが破壊されているので、2、4つのオブジェクトのためのinitメッセージ、およびに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(); 
} 

他の人は一人ままにしておきます。

しかし、私が代わりに取得すると、3、4つのオブジェクトのためのinitメッセージ、およびメッセージのdeallocです:

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.0Thread model: posix

答えて

4

私はOS X 10.9は、あなたが作るていない場合でも、自動的に最上位レベルで作成された自動解放プールがあると考えているので、 1つ(これは、自動リリースプールなしでオートリリースされた、歴史的な "オブジェクトを取り除いた、ちょうど漏れている"警告)。

しかし、これは特にこの状況には関係しません。 ARCは、何かがオートリリースされることを約束していません。後でオブジェクトを使用しないことが証明できる場合は、明示的なリリースを自由に使用できます。 ARCは、強い参照を持つオブジェクトが破棄されないこと、および強い参照がないオブジェクトが破棄されることを保証することのみを義務付けています。 Autoreleasepoolは、ARCが自由に使用できる実装の詳細、またはその裁量で使用されない実装の詳細です。最適化として、ARCは過去に手動で使用していた場所で自動解放プールを回避することがよくあります。

deallocは実際には約束されていないことにも注意してください。プログラムは実行せずに終了することができます(これは、ObjCプログラムがC++プログラムよりも劇的に速く終了することができる大規模な最適化です)。この場合はどうなりますが、deallocに依存して実行している場合や実行していない場合は、おそらくそれを悪用している可能性があります。

関連する問題