2011-08-17 2 views
10

複数回呼び出さ私はこのawakeFromNibメソッドは、私の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はresourceViewを管理し、そのデータを管理するのViewControllerのインスタンスです。マイドキュメントのawakeFromNib方法で

私が持っているmyResourceViewController awakeFromNibの方法で、次のコード

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

を有する:

-(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

+0

はい、私はNSLog(@ "%@"、[self description])でチェックします。 –

+0

myDocument.xibは唯一のnibですか? – paulmelnikow

答えて

31

解決策が見つかりました。 は、NSTableCellViewが作成されるたびに呼び出され、NSOutlineViewによって呼び出されます。

+0

私の場合、awakeFromNibは#回のセル時間と呼ばれていました。しかし、どうしたのですか?サブクラスNSTableCellView? – Mazyod

+2

非常に怒っている、誰もこれを停止する方法を知っていますか? – seanalltogether

+3

回避策ですが、自分のinitでBOOL initialize = NOを設定してから、initialize = NOのときにawakeFromNibでコードを実行します(そしてif文でYESに設定してください) –

4

私はなぜそれが4回呼ばれたのかわかりませんが、少なくとも私はawakeFromNibの2回の呼び出しを考慮することができます。 nibファイルに含まれるオブジェクトだけでなく、ファイルの所有者でもawakeFromNibが呼び出されることを覚えておくことが重要です。

したがって、ResourceViewControllerのawakeFromNibは、myDocument.xibにロードされてから、ResourceViewControllerによって管理されるビューが別のnibからロードされるときに、少なくとも2回呼び出されます。

...didLoadまたはapplicationDidFinish...のような、より明確なタイミングで呼び出される他の方法で初期化を実行する方が良いです。

1

awakeFromNib内の同期ブロック内にコードを挿入します。

例えば

@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がFile Ownerに代理人を設定していることに気付きました。File Ownerに代理人を削除すると、awakeFromNibは一度だけ呼び出されました。

6

根本的な原因は、メソッドmakeViewWithIdentifierのNSTableViewヘッダーファイルに記述されています。 "....所有者は、オブジェクトがインスタンス化されるたびに 'awakeFromNib:'呼び出しを受け取ります。

私のソリューションは単純ですが、私はすべてに適しているとは思っていません。所有者としてtabelView:

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

    return view; 
} 
+2

プロトタイプビューをロードするときには、単に所有者にnilを渡すだけでよい。 –

0

これは把握することは容易ではなかったが、私のために何とか私は私のテーブルビューは、コンテンツモードのための「細胞に基づく」対「表示ベース」に変更しました。

'Cell Based'に戻ってawakeFromNibが1回だけ実行されました。

注:Interface Builderでテーブルビューを3回選択すると、適切なレベルに到達できます。または、ドキュメントのアウトラインから「テーブルビュー」を選択するだけです。

Xcode Attributes Inspector

+0

私はxcode 5.0.2を使用していますが、自分のテーブルの「コンテンツモード」のプロパティを見つけることができません。 – Sawsan

0

ソリューションは、これはawakefromNibは複数回呼び出すことができるようになりmakeViewWithIdentifier:owner:

に自己に所有者を設定することではありません。

関連する問題