多次调用awakeFromNib方法

时间:2011-08-17 11:53:38

标签: objective-c cocoa binding interface-builder xib

在我的基于NSPersistenDocument的项目中,我有一个像这样的结构

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说,myResourceViewController的同一个实例的awakeFromNib被称为4次,我不明白为什么。我唯一的ResourceViewController是在myDocument xib中创建的。我到处都不使用NSNib加载方法。

7 个答案:

答案 0 :(得分:31)

我找到了解决方案。每次awakeFromNib创建NSTableCellView时都会调用NSOutlineView

答案 1 :(得分: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;
}

答案 2 :(得分:4)

我不知道为什么它会被调用四次,但至少我可以考虑两次awakeFromNib的来电。重要的是要记住,即使对于nib文件的文件所有者,也调用awakeFromNib,而不仅仅是nib文件中包含的对象。

因此,您的ResourceViewController的awakeFromNib至少被调用两次:当它在myDocument.xib中加载时,然后当ResourceViewController管理的视图从另一个nib加载时。

最好在其他方法中执行初始化,这些方法在更明确的时间调用,例如...didLoadapplicationDidFinish...

答案 3 :(得分:1)

我将代码放在awakeFromNib中的synchronized块中,就像这样。

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 */
    }
}

答案 4 :(得分:0)

我在NSTableView中注意到了同样的情况。 NSTableView通过NSArrayController更新,我注意到NSTableView已将委托设置为文件所有者,当我将委托删除到文件所有者时,awakeFromNib只调用一次。

答案 5 :(得分:0)

这不容易弄清楚,但对我而言,我的表格视图在内容模式下更改为“基于视图”与“基于单元格”。

切换回'Cell Based'并且awakeFromNib只运行一次。

注意:在Interface Builder中选择三次表格视图以获得正确的级别。或者,只需从“文档大纲”中选择“表视图”。

Xcode Attributes Inspector

答案 6 :(得分:0)

解决方法不是在makeViewWithIdentifier:owner:

中将所有者设置为自己

这使得awakefromNib被多次调用。