2011-12-21 39 views
3

我在寫一個OS X應用程序時遇到了一個非常基本的初始化問題。我在我的NSViewController中初始化initWithNibName中的實例變量。但是,當我在IBAction方法中訪問這些變量時,這些變量將失去它們的價值並最終等於零。實例變量在initWithNib之後和NSViewController中的IBAction之前失去了值

這是我的代碼。我有一個應用程序有1個主窗口和1個NSViewController。應用程序委託以編程方式在applicationDidFinishLoading中調用initWithNibName。該視圖出現,視圖中的按鈕成功調用onButtonClick。但是,在該方法中,myString的值爲空。日誌清楚地表明它在initWithNibName方法期間成功初始化。所以它在initWithNibName和按鈕點擊之間失去了它的價值。

//MyAppDelegate.m 
@implementation MyAppDelegate 

@synthesize window; 

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification 
{ 
    MainView* mainViewController = [[MainView alloc] initWithNibName:@"MainView" bundle:[NSBundle mainBundle]]; 
    [mainViewController loadView]; 
NSView *controllerView = [mainViewController view]; 
    [window setContentView:controllerView]; 
} 

@end 

//MainView.h 
@interface MainView : NSViewController { 
    NSButton *myButton; 
    NSString* myString; 
} 

@property (assign) IBOutlet NSButton *myButton; 
@property (assign) NSString* myString; 

- (IBAction)onMyButtonClick:(id)sender; 

@end 

//MainView.m 
@implementation MainView 

@synthesize myButton; 
@synthesize myString; 

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 
{ 
    NSLog(@"initWithNibName"); 
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 
    if (self) { 
     // Initialization code here. 
     NSLog(@"Initializing..."); 
     [self setMyString:@"try to set the variable"]; 
     NSLog(@"String is %@", myString); 
    } 

    return self; 
} 

- (void)awakeFromNib { 
    NSLog(@"awakeFromNib"); 
    //[self setMyString:@"init in here works, but is called too many times"]; 
} 

- (IBAction)onMyButtonClick:(id)sender{ 
    NSLog(@"Button clicked"); 
    NSLog(@"%@", myString); //Always nil when initialized in initWithNibName()!! 
} 

@end 


//Logs 

initWithNibName 
Initializing... 
String is try to set the variable 
awakeFromNib 
awakeFromNib 
Button clicked 
(null) 

如何讓myString保留其值?

我已經嘗試過所有我能想到的屬性聲明。我也嘗試了各種賦值方法([self setMyString],self.myString = @「blah」,myString = [NSString stringWithFormat:@「blah」]等)。

我讀過我應該在awakeFromNib()中做我的初始化。這實際上工作。然而,我最終的初始化代碼將包含一系列[[MyObj alloc] init]調用,並且當它們被多次調用時,會產生多個指針,並且從那裏發出瘋狂的聲音。我的最終目標是有一個指向對象的指針,控制器可以隨時引用它並始終獲取相同的數據。該對象由控制器初始化,該控制器保存引用,並在用戶與控制器交互時根據需要進行更新。

那麼有沒有什麼辦法在NSViewControllers中初始化實例變量,只有一次,讓它們在控制器的生命週期中保留它們的值?

感謝

千電子伏

+0

我已經將您的代碼複製到測試項目中,並且工作正常。你可能在NIB中設置了錯誤的東西。嘗試創建一個新項目並使用由Xcode自動生成的庫存MainView.xib。 – 2011-12-21 14:46:46

+0

有什麼辦法可以給我發送測試項目的zip文件,以便我可以比較兩者嗎?謝謝。 – Kevin 2011-12-21 15:45:27

+0

http://bit.ly/rGrXI4 – 2011-12-21 22:44:00

回答

0

請允許我回答這個問題,因爲正確答案被埋在我的問題的評論中。

我想出了我做錯了什麼。我爲每個代表視圖控制器的筆尖添加了一個視圖控制器。然後我將按鈕單擊附加到該單獨的視圖控制器對象。 @ Francis-McGrew附上了一個項目,告訴我應該將按鈕點擊附加到文件所有者,然後將文件所有者設置爲視圖控制器。基本上不需要將第二個視圖控制器導入筆尖,只需將文件所有者用作佔位符即可。

1

你應該申報財產(複印件),而不是(分配)

+0

指定和複製是互斥的。你不能擁有兩個。 – 2011-12-21 13:54:02

+0

當然可以。 – 2011-12-21 13:54:40

0

你試過聲明爲(非原子,保留)?

+0

你不應該聲明NSString屬性爲(保留)。有一天,如果你將一個NSMutableString分配給一個保留的NSString屬性,它將會流下眼淚。對於NSArray,NSData等也是如此。 – 2011-12-21 14:02:02

+0

我剛剛嘗試聲明屬性爲「複製」和「保留」,但都沒有成功。但是,我發現了一些新的東西。我添加了一些NSLog語句來打印self和self.myString的內存地址。我將這些NSLog語句添加到了每個initWithNib,awakeFromNib和onMyButtonClick。事實證明,自我匹配的地址在awakeFromNib和onMyButtonClick中。但是該地址與initWithNib中的自身地址不同。很顯然,init初始化了一個與awakeFromNib不同的對象。任何想法爲什麼? – Kevin 2011-12-21 14:38:48