2013-04-08 22 views
2

我有一個奇怪的錯誤與NSViewController其中如果我使用viewcontroller的常規初始化消息分配視圖,創建的視圖不是我的視圖,但使用默認NIB名稱時,它確實工作。NSViewController新與InitWithNibName問題

具體來說,這段代碼一直工作。它創建在nib文件中定義的視圖,並將其顯示在父視圖中。

+ (void)createTransparentViewCenteredInView:(NSView*)parentView withText:(NSString*)text duration:(NSTimeInterval)duration { 
    TransparentAccessoryViewController* controller = [[TransparentAccessoryViewController alloc] initWithNibName:@"TransparentAccessoryViewController" bundle:nil]; 

    NSLog(@"%@", [controller.view class]); // Returns "TransparentAccessoryView" -- CORRECT 
    [parentView addSubview:controller.view]; 
} 

但是,下面的代碼工作一些時間(這是因爲它並不總是失敗怪異)。有了一些父視圖,它工作得很好,而與其他人不一樣。父視圖只是隨機定製的NSViews。是

+ (void)createTransparentViewCenteredInView:(NSView*)parentView withText:(NSString*)text duration:(NSTimeInterval)duration { 
    TransparentAccessoryViewController* controller = [TransparentAccessoryViewController new]; 

    NSLog(@"%@", [controller.view class]); // Returns "NSSplitView" -- INCORRECT 
    [parentView addSubview:controller.view]; 
} 

在出現的錯誤如下(我不知道爲什麼它帶來了一個NSTableView的,因爲我沒有一個NSTableView這裏都沒有。而且,奇怪的是它抱怨的NSTableView的當它打印類型是NSSplitView):

2013年4月7日21:33:12.384無法連接的動作刷新:類TransparentAccessoryViewController的 目標

2013年4月7日21 :33:12.384無法連接操作刪除:目標類TransparentAccessoryViewController

2013年4月7日21的3210:33:12.385 *非法NSTableView的數據源 ()。必須實現 numberOfRowsInTableView:和的tableView:objectValueForTableColumn:行:

的NIB文件定義的子類的NSView定製的,叫TransparentAccessoryView,和掛鉤這份長達文件所有者的視圖屬性,標準的東西(我所做的只是改變自定義類名稱到TransparentAccessoryView)。我添加了NSLog以查看發生了什麼,出於某種原因,在第二種情況下,視圖類類型不正確,並且由於某種原因認爲它是NSSplitView。該視圖控制器類如下:

@implementation TransparentAccessoryViewController 

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { 
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 
    if (self) { 
     // Initialization code here. 
    } 

    return self; 
} 

- (void)awakeFromNib { 
    self.textField.stringValue = @""; 
} 

+ (void)createTransparentViewCenteredInView:(NSView*)parentView withText:(NSString*)text duration:(NSTimeInterval)duration { 
    TransparentAccessoryViewController* controller = [[TransparentAccessoryViewController alloc] initWithNibName:@"TransparentAccessoryViewController" bundle:nil]; 

    NSLog(@"%@", [controller.view class]); 
    [parentView addSubview:controller.view]; 
} 

@end 

我認爲缺省的init消息觸發視圖 - 控制加載視圖 - 控制命名的NIB,這似乎在一定的時間的情況下爲我的代碼的第二個版本在某些條件下工作。

有誰知道爲什麼會發生這種行爲?

+0

你在哪裏得到NSViewController上的'init'的默認實現只需用適當的nib和bundle調用'initWithNibName:bundle'? 'init:withNibName:bundle'是該類的指定初始值設定項,我認爲'init'只需調用'initWithNibName:nil bundle:nil' – 2013-04-08 05:24:27

+0

This [site](http://twobitlabs.com/2012/01/initializing-uiviewcontrollers /)說:「然後由MyController決定如何初始化它的視圖,如果你不覆蓋init,iOS將按照慣例尋找一個與控制器同名的nib(在這種情況下MyController的.xib)。」我知道這是針對iOS的,無法快速找到NSViewController的鏈接,但是我所有其他的NSViewController都是用'new'參數分配和初始化的,它總是加載以ViewController命名的NIB。 – rvijay007 2013-04-08 05:33:25

+0

嘗試使用'[TransparentAccessoryViewController new]'初始化後查看您的自定義viewController的屬性'nibName',以查看它實際加載了哪個nib。該鏈接提到視圖控制器的'init'的實現沒有記錄,並可能在未來版本的SDK中改變 – 2013-04-08 06:08:15

回答

1

我認爲當你在一個NSViewController上調用init時,你假設對於NSViewController的實現init搜索一個與視圖控制器同名的nib並使用它。但是,這是沒有記錄的API,或者至少我似乎無法找到任何支持該假設的文檔。您在評論中發佈的link沒有引用任何文檔,甚至重申這是沒有文檔的,並且Apple可以隨時更改此實現。

我認爲要確保您的代碼在SDK的未來版本中工作(並且因爲它已經在創建不受歡迎的行爲),所以您不應該依賴這個假設。爲了達到同樣的結果只是以這樣的方式覆蓋initinitWithNibName:bundle:this post解釋說:

@implementation MyCustomViewController 

// This is now the designated initializer 
- (id)init 
{ 
    NSString *nibName = @"MyCustomViewController"; 
    NSBundle *bundle = nil; 
    self = [super initWithNibName:nibName bundle:bundle]; 
    if (self) { 
     ... 
    } 
    return self; 
} 

- (id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)bundle 
{ 
    // Disregard parameters - nib name is an implementation detail 
    return [self init]; 
} 
2

the docs

如果您在nibNameOrNil一零通過,則nibName將返回零和 loadView會拋出異常;在這種情況下,您必須在調用視圖之前調用 setView:或覆蓋loadView。

因此,如果你用初始化一個-initNSViewController,你應該叫-setView:設置視圖控制器的視圖,或覆蓋-loadView。在後一種情況下,您當然可以實現您可能期望的類似於UIViewController的行爲 - 如果nibNameOrNil爲零,請嘗試加載與該類具有相同名稱的筆尖。