Objective c 多次调用awakeFromNib方法
在我的基于文档的NSPersistenDocument项目中,我有这样一个结构Objective c 多次调用awakeFromNib方法,objective-c,cocoa,binding,interface-builder,xib,Objective C,Cocoa,Binding,Interface Builder,Xib,在我的基于文档的NSPersistenDocument项目中,我有这样一个结构 myDocument (NSPersistentDocument) -> myDocument.xib (windows xib) | |-> view (the self.view) --> ... "other view"
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是管理resourceView和管理其数据的viewController的实例
在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说同一个myResourceViewController实例的awakeFromNib被调用了4次,我不明白为什么。我唯一的ResourceViewController是在myDocument xib中创建的。我并不在任何地方都使用NSNib加载方法。我不知道为什么它会被调用四次,但至少我可以解释两次awakeFromNib调用。重要的是要记住,awakeFromNib甚至是为nib文件的所有者而调用的,而不仅仅是nib文件中包含的对象 因此,您的ResourceViewController的awakeFromNib至少会被调用两次:当它加载到myDocument.xib中时,以及当ResourceViewController管理的视图从另一个nib加载时
最好在其他方法中执行初始化,这些方法在更确定的时间调用,例如…didLoad或applicationdifinish…我找到了解决方案。每次NSOutlineView创建NSTableCellView时,都会调用awakeFromNib。我将代码放在awakeFromNib中的同步块中,如下所示 e、 g
我在NSTableView中也注意到了同样的情况。NSTableView是通过NSArrayController更新的,我注意到NSTableView将委托设置为文件所有者,当我删除委托给文件所有者时,awakeFromNib只调用了一次。根本原因在方法makeViewWithIdentifier的NSTableView头文件中描述:。。。。请注意,每次实例化对象时,“owner”将得到一个“awakeFromNib:”调用 我的解决方案很简单,但我不希望适用于所有人:只需将TabeView定义为所有者:
- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{
NSTableCellView *view = [tableView makeViewWithIdentifier:kTextViewIdentifier owner:tableView];
return view;
}
这并不容易理解,但对我来说,不知何故,我的表视图在内容模式中改为“基于视图”而不是“基于单元格” 切换回“基于单元”,awakeFromNib只运行一次 注意:在Interface Builder中选择表视图三次,以达到正确的级别。或者,只需从文档大纲中选择“表视图”
解决方案是在makeViewWithIdentifier:owner:
这会使awakefromNib被多次调用。您确定它是同一个对象吗?请尝试NSLog@%p%@,self,[self description]。是的,我使用NSLog@%@,[self description]进行检查;myDocument.xib是唯一的nib吗?不,myResourceViewController有一个名为myResourceViewController.xib的xib。好的,在我的例子中很明显,awakeFromNib被称为单元格时间。。但是,我们的工作是什么?子类NSTableCellView?非常恼火,有人知道如何阻止吗?这是一个解决方法,但我在init中设置了BOOL initialize=NO,然后,仅当initialize=NO时在awakeFromNib中执行代码,并在10.8的if语句中将其设置为YES,您可以使用registernb:forIdentifier:以便它将是另一个加载cellview的nib。@Mazyod解决方案是在makeViewWithIdentifier:owner:加载原型视图时,不允许将所有者设置为self只需将nil传递给所有者。我使用的是xcode 5.0.2,我找不到表的属性内容模式,知道吗?
- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{
NSTableCellView *view = [tableView makeViewWithIdentifier:kTextViewIdentifier owner:tableView];
return view;
}