2016-09-08 5 views
1

オブジェクトがメソッドから返された時点でautoreleaseが呼び出されているすべての例がありますが、メモリの割り当てとオブジェクトの返却の間に例外が発生した場合、これがメモリリークを危険にさらすことはありませんか?だから私は何を意味するか、それは少し明確にするObjective C - return文でautoreleaseが呼び出される前に例外が発生した場合はどうなりますか?

NSString *newString = [[NSString alloc] init]; 
    //Do some other stuff which causes exception 
    return [newString autorelease]; 

@autoreleasepool { 
    try { 
    SomeObject *newObject = [SomeClass generateAutoreleaseObject]; 
    } @catch (NSException *e) { 
     //log exception and carry on. 
    } 
} 

次のようにgenerateAutoreleaseObjectがある場合にメモリリークがありますか?

(SomeObject*)generateAutoreleaseObject { 
     SomeObject *newObject = [[SomeObject alloc] init]; 
     //Do some other stuff which causes exception 
     return [newObject autorelease]; 
    } 

ので、自動解放オブジェクトを返すの基礎クラスはこれを処理しますし、私はそれがURLからの読み込みに問題があったのでstringWithContentsOfURLは約浮動任意のメモリを残していないだろうという知識で私のベッドで今夜は安全簡単に眠ることができる場合?

答えて

1

メモリの割り当てとオブジェクトの返却の間に例外が発生した場合、メモリリークが発生することはありませんか?

はい、そうです。例外は、実行をハンドラに直接渡します。これは、明示的an example in Apple's Cocoa Exceptions Guideに呼び出される:ここ

- (void)doSomething { 
    NSMutableArray *anArray = [[NSMutableArray alloc] initWithCapacity:0]; 
    [self doSomethingElse:anArray]; 
    [anArray release]; 
} 

問題は明白です:doSomethingElse:メソッドが例外をスローした場合、メモリリークがあります。

これを回避するにはどうすればよいですか?例外処理構文には@finallyブロックが含まれています。ブロックは@tryの後に実行され、その後は@catchが実行された後に実行されます。

-generateAutoreleaseObjectで例外が発生する可能性がある場合は、@finallyブロックのローカル例外ハンドラを使用して、リソースがクリーンアップされていることを確認し、必要に応じて例外も再スローします。しかし、内部のCocoaコードについては以下を参照してください!

generateAutoreleaseObjectが次のような場合は、メモリリークがありますか?

はい。 ARCが必ずしもここで助けてくれるわけではないことは注目に値する。再び、制御は、投げた時点からハンドリングのポイントまでをジャンプする。 ARC can't reasonably ensure that it can clean upをデフォルトで使用します。 (あなたが使用できるコンパイラオプションがあること、しかし、そのリンクで見ることができます。)

場合はそうautoreleaseのオブジェクトを返すの基礎クラスは本当にこの

を未処理します。例外がそれらを含むスタックフレームに戻った場合、フレームワーク内部の状態については保証されません。これは避けるのが難しいので、例外はCocoaの回復可能なエラーではないというマントラです。Objective-C ARC and longjmp

+0

恐ろしい答え、感謝:より多くの場合

が、ここでは、このトピック上の2人のアップルのランタイムのエンジニアです。 – Travis

関連する問題