2010-10-21 49 views
3

我使用基於視圖的應用程序模板創建了一個新的Xcode項目。在視圖控制器的.m中覆蓋了這個:爲什麼我的UIViewController的指定初始化程序從未被調用過?

// The designated initializer. Override to perform setup that is required before the view is loaded. 
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { 
    if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) { 
     // Custom initialization 

     NSLog(@"initWithNibName..."); 
    } 
    return self; 
} 


- (id)init { 
    NSLog(@"initWithNibName..."); 
    return [super init]; 
} 

但是,我從來沒有得到NSLog。這也是我從其他項目獲得的經驗。這種方法從來沒有被調用。甚至沒有NSObject的-init。

視圖控制器是在XIB文件內部創建的。這怎麼可能,Nib加載系統在沒有任何初始化的情況下實例化這個類?

爲什麼?什麼是替代而不是-loadView和-viewDidLoad?

遠離XIB文件的另一個重要原因是什麼?

回答

9

從IOS Resource Programming Guide

在iPhone OS,符合NSCoding協議使用initWithCoder:方法中初始化的任何對象。這包括UIViewUIViewController的所有子類,無論它們是默認Interface Builder庫還是您定義的自定義類的一部分。

想想這樣:當您的視圖控制器是在Interface Builder中首次創建時調用指定的初始化程序。然後,當您保存nib文件時,視圖控制器實例將存儲在文件中。稍後,當加載nib時,將從nib重新創建實例。

由於第一次重新創建而不是創建,因此使用了不同的初始化方法。此方法(-initWithCoder:)使用nib文件中的值恢復對象的狀態,該值可以包含除由指定初始化程序設置的屬性以外的屬性設置。這種機制依賴於協議,它允許它對於許多不同的類一般工作。

+0

應該注意,initWithNibName:bundle:將在你使用一個nib並通過直接調用initWithNibName:bundle:來實例化視圖控制器時被調用。通常情況下,這些日子你正在使用故事板,在這種情況下,它會調用initWithCoder:相反。在故事板之前,我猜測默認的Xcode項目基於視圖的應用程序模板沒有調用initWithNibName:bundle:來初始化初始視圖控制器。 – 2015-02-06 02:35:11

+0

@LironYahdav如果你重讀這個問題,你會注意到它表明視圖控制器在* nib文件中,所以在加載nib時不能調用'initWithNibName:bundle:'。 – jlehr 2015-02-06 14:28:15

1

你可以使用 - awakeFromNib來做這個。 只有在代碼中這樣做時纔會調用init。

+0

謝謝你的提示!但無論如何,Nib Loader如何創建此類的實例而不執行任何初始化? – 2010-10-21 11:57:03

+2

所有從NIB(或另一個NSCoding歸檔文件)加載的對象都使用'-initWithCoder:'進行初始化。 – 2010-10-21 11:58:56

+1

是有道理的,但爲什麼-init從未被調用?它是NSObject的指定初始化程序... – 2010-10-21 12:37:38

0

你把你的MainWindow委託設置爲你的appDelegate ..? 在您的AppDelegate和applicationDidFinishLaunching Methode中執行UIApplicationDelegate,嘗試initWithNibName。 這將做到這一點。

相關問題