2011-09-23 102 views
1

我無法分配一個類的實例以下UITableViewController子類屬性:麻煩與Objective-C的

@interface MyTableViewController : UITableViewController </*usual protocols*/> 
@property (nonatomic, retain) MyClass *myClass; 
@end 

我目前分配MyClass的一個非空實例的實例MyTableViewController這樣的:

MyTableViewController *myTableViewController = [[MyTableViewController alloc] init]; 
MyClass *nonNullInstanceOfMyClass = [[MyClass alloc] init]; 

myTableViewController.myClass = nonNullInstanceOfMyClass; 

[self.navigationController pushViewController:myTableViewController animated:YES]; 

[nonNullInstanceOfMyClass release]; 
[myTableViewController release]; 

的問題是,MyClass的是MyTableViewController的viewDidLoadnull這是怎麼發生的?

編輯#1:我通過NSLogging檢查nonNullInstanceOfMyClass是否爲空。

編輯#2:提供了更多的代碼。另外viewDidLoad似乎被調用之前,我推視圖控制器(這可能會導致問題......雖然它似乎很奇怪)。

編輯#3:通過從移動initself.tableView.delegate = nil;self.tableView.dataSource = nil;固定viewDidLoad

+0

所以你是說你把它設置爲一個非空實例,然後viewDidLoad中被調用,當您檢查MyClass的在那個函數中它是空的? – sashang

+2

描述你如何知道nonNullInstanceOfMyClass不爲null。 – thomashw

+0

@sashang是的,這是正確的。 – SundayMonday

回答

0

你是否在做實例化視圖控制器和分配屬性之間的任何事情?當您將視圖控制器推入導航堆棧時,不一定會調用viewDidLoad - 只要需要加載視圖就會調用它。因此,例如,NSLog(@"%@", myTableViewController.view);會觸發viewDidLoad,如果您在分配屬性之前執行了此操作,則可以解釋此行爲。

你能發佈實際代碼而不是近似值嗎?可能會有重要的細節被遺漏。

+0

經過進一步調查,在我分配nonNullInstanceOfMyClass之前,會出現'viewDidLoad'。但是在我推視圖控制器之前,我正在分配nonNullInstanceOfMyClass。 – SundayMonday

+0

@MrMusic:那不就是發現回答問題嗎? – sashang

+0

然後,問題是在視圖控制器的實例化中,或者在該點與屬性分配之間。在某些時候,您正在訪問視圖控制器的'view'屬性,這會啓動'viewDidLoad'。 – Jim

0

viewDidLoad在從xib加載視圖時觸發。

這裏有幾個選項。

最簡單的就是在viewDidAppear:方法

- (void)viewDidAppear:(BOOL)animated 
{ 
    // Handle what you want for when your view has become visible. 
    // This may happen more then once. So a flag for the first time will 
    // give you a sufficient Limit for Initialization 
} 

或者存在viewWillAppear中:

另一種選擇是有IB加載類這樣的想你不是null。並將可在viewDidLoad:

您的MyClass將需要是一個UIView。

您將UIView(作爲佔位符)放置到TableViewController的視圖中您想要的位置。

然後,您可以在「界面生成器」中的「自定義類」下的「標識」檢查器中設置其類類型。

最後拖動從IBOutlet中

@property (nonatomic, retain) IBOutlet MyClass *myClass; 

到您的自定義類的UIView界面生成器連接

然後,當界面生成器初始化類將填充該屬性與該類的一個空白實例。

第三個選擇將是一個懶惰的負載特性

這裏是我怎麼做懶加載

//we will take for granted that your @property is in the header 
//and the following Synthesize is on the class 
@synthesize myClass=_myClass; // setting instance variable to avoid confusion 
- (MyClass*) myClass 
{ 
    if (_myClass == nil) _myClass = [[MyClass alloc] init];//Create a default instance and retain it 
    return _myClass; 
} 

然後使用self.myClass和你的getter方法會爲您創建一個。

編輯:

我加入了= _myClass到@synthesize從財產

這種方式使用myClass的會產生一個錯誤,你將不得不使用自走改變實例變量.myClass獲取屬性訪問器。

+0

我應該提到我沒有使用接口構建器。 – SundayMonday

+1

well viewDidLoad應該在類初始化並準備好使用時觸發。如果不設置屬性,它將在viewDidLoad中爲null。懶惰的加載器怎麼樣?生病更新示例 –

-1

更改以下行從:

@property (nonatomic, retain) MyClass *myClass; 

到:

@property (nonatomic, assign) MyClass *myClass; 
+0

這將如何幫助? – SundayMonday

+0

不知道它會,但是因爲你正在調用的類之外​​創建myClass實例,所以該類不是真正的所有者。您的實例可能會通過'retain'生成的代碼發佈, –