2011-08-17 142 views
10

在我NSPersistenDocument基於項目我有這樣awakeFromNib方法調用多次

myDocument (NSPersistentDocument) -> myDocument.xib (windows xib) 
              | 
              |-> view (the self.view) --> ... "other view" 
              | 
              |-> some NSArrayController 
              | 
              |-> myResourceViewController --> myResourceViewController.xib 
                          | 
                          |-> view (the self.view) 
                          | 
                          |-> myTreeController (a NSTreeController subclass) 

基本的結構,myResourceViewController是的viewController的實例,誰管理的ResourceView和管理他們的數據。

在myDocument中的awakeFromNib方法

我有下面的代碼

- (void)windowControllerDidLoadNib:(NSWindowController *)aController 
{ 
    ... 
    [leftBar addSubview:resourceViewController.view]; //i add resourceViewController's view 
    resourceViewController.view.frame = leftBar.bounds; 
    ... 
} 
在myResourceViewController awakeFromNib方法

我有:

-(void)awakeFromNib; 
{ 
    NSLog(@"%@", [self description]); 

    [removeButton bind:@"enabled" toObject:resourceTreeController withKeyPath:@"selection" options:[NSDictionary dictionaryWithObject:NSIsNotNilTransformerName forKey:NSValueTransformerNameBindingOption]]; 

    NSArray *draggedTypes = [NSArray arrayWithObjects:ResourceURIPasteBoardType, nil]; 
    [resourceOutlineView registerForDraggedTypes:draggedTypes]; 
} 

的NSLog的說awakeFromNib,myResourceViewController的同一個實例中,被稱爲4次,我不明白爲什麼。我唯一的ResourceViewController是在myDocument xib中創建的。我不使用NSNib加載方法。

+0

你確定它是同一個對象嗎?試試`NSLog(@「%p%@」,self,[self description])``。 – hamstergene 2011-08-17 12:01:01

+0

是的,我檢查NSLog(@「%@」,[self description]); – 2011-08-17 12:03:44

+0

myDocument.xib是否是唯一的筆尖? – paulmelnikow 2011-08-17 15:14:21

回答

31

我找到了解決方案。每次由NSOutlineView創建NSTableCellView時,都會調用awakeFromNib

4

我不知道爲什麼它被稱爲四次,但至少我可以解釋兩次調用awakeFromNib。重要的是要記住,即使對於nib文件的文件所有者,也不僅調用awakeFromNib,而且還要調用nib文件中包含的對象。

因此,您的ResourceViewController的awakeFromNib會被調用至少兩次:它在myDocument.xib中加載時,然後由另一個nib加載由ResourceViewController管理的視圖時。

最好在其他方法中執行初始化,在更確定的時間調用,例如...didLoadapplicationDidFinish...

1

我把代碼放在我awakeFromNib的同步塊裏面,像這樣。

e.g

@implementation { 
    BOOL _initialize; 
} 

    - (id)init { 
     self = [super init]; 
     if (self) { 
      _initialize = YES; 
     } 
     return self; 
    } 

    - (void)awakeFromNib { 
     @synchronized(self) { 
      if (_initialize) { 
       _initialize = NO; 

       /* code to execute once */ 
      } 
     } 

     /* code to re-execute */ 
    } 
} 
0

我注意到NSTableView的相同。 NSTableView通過NSArrayController更新,我注意到NSTableView有委託設置爲文件所有者,當我刪除委託給文件所有者時,awakeFromNib只調用一次。

6

根本原因在方法makeViewWithIdentifier的NSTableView頭文件中描述:「....請注意,每次對象被實例化時,'owner'都會得到一個'awakeFromNib:'調用。

我的解決方案很簡單,但我預計不適合所有人:只需定義例如在tabelView作爲所有者:

- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row 
{ 
    NSTableCellView *view = [tableView makeViewWithIdentifier:kTextViewIdentifier owner:tableView]; 

    return view; 
} 
0

這是不容易弄清楚,但「基礎論」「基於細胞」我不知我我的表視圖改變,相較於內容模式。

切換回「基於單元格」,而awakeFromNib只運行一次。

注意:在Interface Builder中選擇三次表格視圖以達到正確的級別。或者,從「文檔大綱」中選擇「表格視圖」。

Xcode Attributes Inspector

0

的解決方案是不是要設置業主中自makeViewWithIdentifier:owner:

這使得awakefromNib被多次調用。