2014-07-22 24 views
0

我想知道是否可以將NSWindow的引用傳遞給自定義對象,然後使用該對象爲該按鈕添加NSButton和相關的動作/選擇器。我可以將NSWindow的引用傳遞給自定義對象,並使用該對象添加NSButton和Action?

我嘗試這個時似乎遇到問題。當我運行示例程序並點擊按鈕,會出現以下運行時錯誤: 線程1:EXC_BAD_ACCESS(代碼= 1,地址=爲0x18)

這裏是我的代碼:

// AppDelegate.h 

#import <Cocoa/Cocoa.h> 

@interface AppDelegate : NSObject <NSApplicationDelegate> 
@property (assign) IBOutlet NSWindow *window; 
@end 

// AppDelegate.m 

#import "AppDelegate.h" 
#import "CustomObject.h" 
@implementation AppDelegate 

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification 
{ 
    CustomObject *test = [[CustomObject alloc]init]; 
    [test createButton:_window]; 
} 
@end 


// CustomObject.h 

#import <Foundation/Foundation.h> 

@interface CustomObject : NSObject 
{ 
    int test; 
    NSButton *testButton; 
} 
- (IBAction)pressCustomButton:(id)sender; 

-(void)createButton:(NSWindow*)win; 
@end 

// CustomObject.m 

#import "CustomObject.h" 

@implementation CustomObject 

-(IBAction)pressCustomButton:(id)sender 
{ 
    NSLog(@"pressCustomButton"); 
} 

-(void)createButton:(NSWindow*)win 
{ 
    testButton = [[NSButton alloc] initWithFrame:NSMakeRect(100, 100, 200, 50)]; 

    [[win contentView] addSubview: testButton]; 
    [testButton setTitle: @"Button title!"]; 
    [testButton setButtonType:NSMomentaryLightButton]; //Set what type button You want 
    [testButton setBezelStyle:NSRoundedBezelStyle]; //Set what style You want 

    [testButton setTarget:self]; 
    [testButton setAction:@selector(pressCustomButton:)]; 
} 
@end 

回答

1

第一關,我假設你正在使用自動引用計數。

當您單擊該按鈕時,應用程序會嘗試調用該按鈕的目標的pressCustomButton:方法,CustomObject的實例將其設置爲自身。但是,該實例CustomObject已被釋放。

看看下面的代碼:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification 
{ 
    CustomObject *test = [[CustomObject alloc]init]; 
    [test createButton:_window]; 
} 

一旦該方法完成調用,如果你正在使用ARC,您所創建的CustomObject實例將被釋放。由於NSControl子類(如NSButton)不保留其目標(以避免保留週期/強引用週期),因此還會導致實例被解除分配。這將導致該實例的任何後續消息產生意外的結果,例如崩潰。

爲了防止出現這種情況,您需要將CustomObject實例保留在applicationDidFinishLaunching:方法之外。有一對夫婦的這樣做的方式,如使其成爲AppDelegate的屬性,或者如果您計劃在具有多個對象,請使用NSMutableArray將它們存儲在

像下面這樣:

@interface AppDelegate : NSObject <NSApplicationDelegate> 
.... 
@property (nonatomic, strong) NSMutableArray *customObjects; 
@end 

// AppDelegate.m 

#import "AppDelegate.h" 
#import "CustomObject.h" 
@implementation AppDelegate 

- (id)init { 
    if ((self = [super init])) { 
     customObjects = [[NSMutableArray alloc] init]; 
    } 
    return self; 
} 

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification 
{ 
    CustomObject *test = [[CustomObject alloc]init]; 
    [customObjects addObject:test]; 
    [test createButton:_window]; 
} 
@end 
相關問題