0

クラスのインスタンスがそれ自体のプロパティを監視する必要があるため、監視を設定します。

[self addObserver:self forKeyPath:@"myProperty" options:NSKeyValueObservingOptionNew context:nil]

そして、dealloc では、オブザーバーをチェックして削除するだけです。

- (void)dealloc
{
    if ([self observationInfo])
    {
        [self removeObserver:self];
    }
}

このプロジェクトは ARC の下にあり、iOS 6 SDK より前ではすべて正常に動作します。しかし、iOS 6 SDK では、EX_BAD_ACCESS (解放メッセージが割り当て解除されたインスタンスに送信された)observationInfoの後で、オブジェクトとアプリのretainCount を増やしてクラッシュします。dealloc

このコードのどこが間違っていますか? それはAppleのバグですか、それとも私のものですか?

UPDATE スタックトレースがあります:

thread #1: tid = 0x1f03, 0x016b60ab libobjc.A.dylib`objc_release + 27, stop reason = EXC_BAD_ACCESS (code=1, address=0xff000002)

frame #0: 0x016b60ab libobjc.A.dylib`objc_release + 27
frame #1: 0x016b6bd9 libobjc.A.dylib`(anonymous namespace)::AutoreleasePoolPage::pop(void*) + 555
frame #2: 0x02538468 CoreFoundation`_CFAutoreleasePoolPop + 24
frame #3: 0x0253cafd CoreFoundation`__CFRunLoopRun + 1933
frame #4: 0x0253bf44 CoreFoundation`CFRunLoopRunSpecific + 276
frame #5: 0x0253be1b CoreFoundation`CFRunLoopRunInMode + 123
frame #6: 0x024f07e3 GraphicsServices`GSEventRunModal + 88
frame #7: 0x024f0668 GraphicsServices`GSEventRun + 104
frame #8: 0x0022e65c UIKit`UIApplicationMain + 1211
frame #9: 0x00001efd MyProjects`main + 141 at main.m:16
4

2 に答える 2

7

を呼び出すと[self observationInfo]、 が保持され、自動解放されselfます。しかし、あなたはすでに にいるのでdealloc、自動解放プールが空になる前にオブジェクトの割り当てが解除されます。そのため、自動解放プールが最終的に空になると、割り当てが解除されたオブジェクトを解放しようとしてクラッシュします。これは、スタック トレースで確認できます。フレーム #2 はCFAutoreleasePoolPop、自動解放プールを空にする関数である への呼び出しです。

于 2012-12-10T21:05:09.387 に答える
1

-observationInfo は、このために設計されていません。KVO を設定したかどうかを本当に知りたい場合は、何らかのフラグをインスタンス変数として保存します。

于 2012-12-10T20:43:50.753 に答える