2017-01-11 2 views
1

私は説明できないNSUndoManagerのクラッシュの原因となるいくつかのiOS Objective-Cサンプルコード(より大きなプロジェクトから簡略化された)をいくつか持っています。NSUndoManager removeAllActionsWithTargetクラッシュ

すなわち

、(それがアンドゥのレベルを超えてだから)、およびのみNSUndoManagerのdeallocsによって上に保持されているオブジェクトは、docsコールremoveAllActionsWithTarget:selfによれば、私はEXC_BAD_ACCESSを取得します。ボタン(+ 1 levelsOfUndo)の第4回タップ後

// SimpleViewController.m 
@interface ViewController() 
@property (nonatomic, strong) NSUndoManager *undoManager; 
@end 

@implementation ViewController 

@synthesize undoManager; 

// called from a simple button 
- (IBAction)doItTapped:(id)sender 
{ 
    CoolObject *object = [CoolObject new]; 
    object.undoManager = self.undoManager; 
    // according to docs, object will be retained by NSUndoManager here 
    // but target will not (which should be okay) 
    [self.undoManager registerUndoWithTarget:self selector:@selector(notCool:) object:object]; 
} 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    self.undoManager = [NSUndoManager new]; 
    self.undoManager.levelsOfUndo = 3; 
} 

// CoolObject.m 
@implementation CoolObject 

- (void)dealloc 
{ 
    [self.undoManager removeAllActionsWithTarget:self]; 
} 

@end 

、それがクラッシュ。 NSUndoManagerをGCUndoManagerと交換するとクラッシュしません。 iOS 10.2 simおよびデバイスでテスト済みです。

ありがとうございました!

答えて

0

self.undoManagerは、使用している時点で保持されないため、このエラーが発生する可能性があります。オブジェクトがすでに割り当て解除され、アクセスしようとすると、不正なアクセス例外が発生します。

このことから、あなたのコードを変更してみてください。これに

CoolObject *object = [CoolObject new]; 

@interface ViewController(){ 
CoolObject *object; 
} 
@property (nonatomic, strong) NSUndoManager *undoManager; 
@end 
@implementation ViewController 
- (IBAction)doItTapped:(id)sender 
{ 
    object = [CoolObject new]; 
    object.undoManager = self.undoManager; 
    // according to docs, object will be retained by NSUndoManager here 
    // but target will not (which should be okay) 
    [self.undoManager registerUndoWithTarget:self selector:@selector(notCool:) object:object]; 
} 
@end 

これが役立つことを願っています。

+0

ダイスがなくてもクラッシュします。それはundoManager自体にではなく、undoManagerに渡された 'self'をクラッシュさせます。これは主なコードでは、UndoManagerはアプリのライフサイクル全体に存在するシングルトンなので、UndoManagerが解放されていないことは間違いありません。 – Thomas

関連する問題