2014-01-06 11 views
5

__autoreleasingキーワードの使用方法を理解していらっしゃると思います。Objective-Cです。__autoreleasingの使用方法の詳細が必要です

In which situations do we need to write the __autoreleasing ownership qualifier under ARC?

Use of __autoreleasing in code snippet example

NSError and __autoreleasing

、今にもかかわらず、私はまだ主なもの、目的を得ることができない、より理解:私は徹底的に以下の質問への回答を読みました。それはなぜですか?正確に私を混乱させるものを説明しましょう。コードを考えてみましょう:

@interface MyError : NSError 

@end 

@implementation MyError 

- (void)dealloc 
{ 
    NSLog(@"My error dealloc"); 
} 

@end 

@interface ErrorHandler : NSObject 

- (void)handleError:(MyError* __strong*)error; 

@end 

@implementation ErrorHandler 

- (void)handleError:(MyError* __strong*)error 
{ 
    *error = [[MyError alloc] initWithDomain:@"Blabla" code:100500 userInfo:@{ 

                      NSLocalizedDescriptionKey : @"TestDescription" 


                      }]; 
} 

@end 

- (void)test 
{ 
    MyError *error = nil; 

    ErrorHandler *handler = [ErrorHandler new]; 

    [handler handleError:&error]; 

    NSLog(@"Localized description %@", error.localizedDescription); 
} 

私は__autoreleasingを使用しない場合は何が起こるかを確認するには、このコードを書きました。表示されるように、handleErrorメソッドは、明示的にと宣言された参照への参照を受け入れます。そして何も起こらない。全て大丈夫。私はMyErrorオブジェクトから情報を取得することができ、それは正常に割り当て解除されている、私はそれを参照してください。もし私が__strongの代わりに__autoreleasingを入れても何も変わりません。なぜそれが何も変わらないならば__autoreleasingを使うのはなぜですか?これは私が理解していないものです。誰かが私に行方不明を見せてもらえますか?おかげで誰も

+0

http://stackoverflow.com/questions/14554121/what-are-the-advantages-of-declaring-method-arguments-autoreleasingをチェックしましたか? –

+0

はほんの数分前に見つかりました –

答えて

9

私はあなたがしたい場合は、弱い参照へのポインタを渡すことができます__autoreleasingとして引数を宣言することによって、だと思う。

は、あなたの方法は次のようになります想像:

-(void) handleError: (NSError* __strong *) error 
{ 
    NSError* myError = [[NSError alloc] init]; 
    *error = myError; 
} 

コンパイラは*errorが強いので、それは割り当てを行うとき、あなたは1保持カウントを取得すると思います。コンパイラは、コードの上にされた後、それは次のようになります。

-(void) handleError: (NSError* __strong *) error 
{ 
    NSError* myError = [[NSError alloc] init]; 
    *error = [myError retain]; 
    [myError release]; 
} 

あなたはこのようにそれを呼び出すのであれば:

NSError* error; // strong reference 
[self handleError: &error]; 

コンパイラがで正しくリリースを配置しますので、それはすべての罰金ですスコープの終わり。あなたはこのかかわらず行う場合:

NSError* __weak error; // weak reference 
[self handleError: &error]; 

をそれはおそらくコンパイルされませんが、それはなかった場合、コンパイラは(それがhandleError:に強いの割り当てを見ることができない)の参照が弱いと考えているので、それは入れません。リリースではオブジェクトがリークします。あなたはこのようなメソッドを定義する場合

:それは次のようになりますので、

-(void) handleError: (NSError* __weak *) error 
{ 
    NSError* myError = [[NSError alloc] init]; 
    *error = myError; 
} 

コンパイラは、コードを追加します。

*errorの割り当ては0カウントを保持していますので、それはさらに悪いです
-(void) handleError: (NSError* __weak *) error 
{ 
    NSError* myError = [[NSError alloc] init]; 
    *error = myError; 
    [myError release]; 
} 

つまり、myErrorが有効範囲外になるとすぐに、つまりメソッドが返ってくると、それがポイントするオブジェクトの割り当てが解除されます。

あなたはこれを行う場合:

コンパイラはこの行い
-(void) handleError: (NSError* __autoreleasing *) error 
{ 
    NSError* myError = [[NSError alloc] init]; 
    *error = myError; 
} 

、返されるオブジェクトはの終わりに自動解放プールにあるを除いて、前の場合と同じである
-(void) handleError: (NSError* __autoreleasing *) error 
{ 
    NSError* myError = [[NSError alloc] init]; 
    *error = [[myError retain] autorelease]; 
    [myError release]; 
} 

このメソッドは解放されません。したがって、呼び出し元にerrorを強か弱かのどちらかと宣言することができ、コンパイラは返された参照で賢明なことをする機会を得ます。

少なくとも私はそれが問題だと思います。

関連する問題