2011-02-28 21 views
6

我有一個UIView子類,我想從一個NIB文件實例化。我一直在使用這種方法來做到這一點:使用NIB文件實例化一個帶有委託的UIView子類

UINib *nib = [UINib nibWithNibName:@"SSNodeToolsView" bundle:[NSBundle mainBundle]]; 
self = [[[nib instantiateWithOwner:self options:nil] objectAtIndex:0] retain]; 

...實際上,這會正確創建對象並將所有內容鏈接起來。但是,該對象立即失去對其委託的訪問權限。代表按照常規方式聲明:

id delegate 
@property (nonatomic, assign) id delegate 
@synthesize delegate 

...等等。但是,當對象從其筆尖加載時,委託立即變爲空,並忽略爲其分配值的任何嘗試。奇怪這不會導致崩潰。誰能告訴我爲什麼這是?我寧願使用nib加載方法,因爲我的應用程序的這些元素很可能會經常重新設計,使用nib最容易做到這一點。

-Ash

回答

7

編輯:將關鍵點移到頂部。您不能同時創建一個對象,並將其全部設置爲文件的所有者。文件的所有者需要是一個已經存在的初始化對象,並且沒有零售ivars,以便將筆尖加載正確連接到所有者的插座。

委託對象是否也在筆尖?如果沒有任何東西保留它(你的財產是'分配'),它可能會在下一個自動釋放池消失。代表是你的筆尖的出口嗎?裝入筆尖後,插座中的「無」值通常表示插座連接不正確。另外,看起來你正在使用一個尚未初始化的owner對象(self)實例化nib。如果是這樣,您的插座可能無法正確連接,因爲只有在所有者對象中的相應值爲零時才連接插座。在將其用作加載筆尖的所有者之前,您應該擁有完全初始化的所有者對象。

這裏的「負荷從筆尖這個對象」的初始化代碼我在項目之一使用:

- (id)initWithFrame:(CGRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    if (self) 
    { 
     // Initialization code. 
     // 
     [[NSBundle mainBundle] loadNibNamed:@"ScoreView" owner:self options:nil]; 
     [self addSubview:self.view]; 
    } 
    return self; 
} 

- (void) awakeFromNib 
{ 
    [super awakeFromNib]; 

    [[NSBundle mainBundle] loadNibNamed:@"ScoreView" owner:self options:nil]; 
    [self addSubview:self.view]; 
} 

使用筆尖有一個內置的間接,你無法避免的水平。您不能創建一個對象,並同時將其用作文件所有者 - 所有者必須已經存在,並在筆尖加載時初始化(無零點)。

使用上面的代碼,我可以從代碼創建我的對象或將其直接放置到其他nib文件 - 可重用的UIView組件。

+0

啊哈,謝謝!這就是爲什麼。我正在改變一種更簡單的方法,即將自定義視圖依賴於視圖控制器並直接從按鈕發送IBActions。那是我仍然可以使用NIB – Ash 2011-03-01 18:15:53

+0

是的,這是有效的,但你不必。我在自定義的UIView子類中使用上述代碼,這些子類不屬於視圖控制器。這是一條相當好的路線 - 視頻控制器方法肯定有一些好處,但感覺更「重量級」。除非您自己手動將這些調用轉發給子視圖控制器,否則您無法獲得某些好處(viewWill/Did/Appear/Disapper)。 – Bogatyr 2011-03-01 18:51:14

+0

其真的不錯 – GameLoading 2011-06-10 06:16:38