2009-10-19 60 views
12

我開始將更多的視圖層次結構轉移到IB。爲什麼我的awakeFromNib不會啓動?

我有一個名爲「AlignmentViewController.xib」的筆尖文件,其中我使用AlignmentViewController作爲文件所有者設置了我的視圖層次結構。這工作正常。

我仍然模糊的方法之一是awakeFromNib。在下面的AlignmentViewController代碼片段中,我添加了一個額外的方法awakeFromNib。然而,它不會被稱爲:

- (void)awakeFromNib { 

    NSLog(@"AlignmentViewController - awakeFromNib"); 
    [super awakeFromNib]; 

} 

- (id)initWithChromosomeName:(NSString *)chromosomeName 
       basepairStart:(NSUInteger)basepairStart 
       basepairEnd:(NSUInteger)basepairEnd { 

    self = [self initWithNibName:@"AlignmentViewController" bundle:nil]; 

    if (nil != self) { 


     self.title   = @"Alignment"; 

     self.chromosomeName = chromosomeName; 
     self.basepairStart = basepairStart; 
     self.basepairEnd = basepairEnd; 

     self.wantsFullScreenLayout = YES; 

    } 

    return self; 
} 

有人可以澄清我在這裏錯過了什麼?

乾杯, 道格

UPDATE: 讀一些我知道的答案後,我需要得到的東西的底部,這是非常基本的。

望着初始化:

- (id)initWithChromosomeName:(NSString *)chromosomeName 
       basepairStart:(NSUInteger)basepairStart 
       basepairEnd:(NSUInteger)basepairEnd { 

    self = [self initWithNibName:@"AlignmentViewController" bundle:nil]; 

我發現我打電話initWithNibName:包:間接。這是不好的做法嗎? AlignmentViewController.xib文件定義了我的視圖層次結構。但我沒有真正使用initWithNibName:bundle:通常的方式?有一個更好的方法嗎?

+2

FWIW,UIViewController中還提供了'viewDidLoad'專門爲你需要在你的控制器做,視圖已經被加載(無論是手工還是從筆尖)之後的任何處理。 – 2009-10-19 14:14:04

+0

是的。我廣泛使用viewDidLoad。我只是試圖將更多的UI構建移植到IB,並且我需要在某個時候處理awakeFromNib。 – dugla 2009-10-19 15:31:55

+3

IB的使用沒有要求使用'awakeFromNib',也不違反對'viewDidLoad'的使用。 – 2009-10-19 16:15:47

回答

30

-awakeFromNib發送到在所有nib對象實例化後從nib實例化的所有對象。所有者不是這些對象之一。它在反序列化筆尖之前存在,並且在加載後連線到筆尖,因此它不會被髮送(除非它被其他筆尖本身實例化)。

這裏的一個線索是,-initFromChromosomePair:basepairStart:basepairEnd:-awakeFromNib都不能被調用。筆尖加載器始終調用-initWithCoder:,-initWithFrame:-init(其發送規則在Nib Object Life Cycle中)。事實上,你有一些其他指定的初始化器強烈建議你在代碼中的某處手動創建這個對象,這意味着這個對象不是「從筆尖喚醒」。

+0

感謝羅布,我想我不清楚initWithNibName:bundle:的語義。在我的代碼中,我確實調用了initWithChromosomeName:basepairStart:basepairEnd:它依次調用initWithNibName:bundle:如上所示。由於使用initWithNibName:bundle:而不會觸發與nib相關的方法嗎? – dugla 2009-10-19 15:26:44

+3

許多火災;它們只是針對由nib加載器實例化的對象。筆尖的所有者不在*筆尖中,因此不會得到-awakeFromNib。 -viewDidLoad被髮送到視圖控制器,這是在你完成加載之後需要完成的事情。請注意,視圖控制器可以位於筆尖中,因此可以同時接收-awakeFromNib(當它從父級筆尖加載時)和後來的-viewDidLoad(當它自己的筆尖加載完成時)。 -awakeFromNib被髮送到筆尖中的所有對象都被實例化並且IBOutlet被連線之後的一個筆尖中的所有對象。 – 2009-10-19 17:01:03

+0

現在我明白了。感謝羅布,這真的清除了事情。我忽略了這樣一個事實,即filesOwner只是一個代理,而不是nib的成員。涼意。感謝一百萬Rob。 – dugla 2009-10-19 18:38:58

2

根據你告訴我們,我相信我知道你的問題是什麼。當從nib文件反序列化對象時調用awakeFromNib。在這裏你有一個物體,它是所有者,存在之前的筆尖加載。因此awakeFromNib永遠不會被髮送到您的AlignmentViewController.h

如果您需要在此處執行操作,請嘗試使用loadView。或者在加載筆尖之後進行。你打算怎麼做,你想在awakeFromNib做什麼?

+0

謝謝戈登。試圖圍繞與筆尖相關的代碼的語義和時間來更好地進行分析。我正在越來越多地依賴IB來構建UI,我仍然不確定IB世界和XCode世界如何同步。所以,不要使用nib相關的方法激發我使用initWithNibName:bundle:? – dugla 2009-10-19 15:30:17

+0

不,這是'awakeFromNib'沒有在你的控制器上調用,因爲你的控制器不在nib中。它會在所有的視圖上被調用,並且在筆尖中。 – 2009-10-19 16:14:38

+1

請注意,在上面Gordon所說的「loadView」中,我相信他的意思是「viewDidLoad」。在處理基於筆尖的視圖控制器時,您通常不應該混淆-loadView。 – 2009-10-19 17:02:24

32

只需添加一個說明:-awakeFromNib發送給Cocoa的文件所有者,但不是Cocoa Touch。

From Apple's Docs:

...

  • 它發送一個消息awakeFromNib在筆尖文件定義匹配選擇適當的對象:
    • 在Mac OS X,該消息被髮送到定義該方法的任何接口對象。它也被髮送到文件的所有者和定義它的任何代理對象。
    • 在iPhone OS中,此消息僅發送給由nib加載代碼實例化的接口對象。它不會發送到文件所有者,第一響應者或任何其他代理對象。
相關問題