2011-08-17 179 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被多次调用。