2012-02-20 84 views
2

我有一個UIViewController的子類,NSMutableArray作爲一個屬性用作UITableView的數據源。我在故事板中創建了一個類的實例。(iOS)作爲屬性addObject的NSMutableArray什麼都不做

我想用addObject:方法填充數組,但如果我嘗試,數組總是返回(null)

,我讀了@synthesize不初始化數組和我可能需要重寫-init和初始化的NSMutableArray有,但-init不會被調用。

這是怎麼應該工作?

+0

什麼是具有'NSMutableArray'屬性的類?它的超類是什麼?你是在代碼中還是在筆尖或故事板中創建類實例? – 2012-02-20 06:57:13

+0

它是鏈接到故事板視圖的UIViewController的子類。 – TijuanaKez 2012-02-20 07:08:09

回答

5

您需要創建一個NSMutableArray的實例並將其分配給屬性。

由於具有該屬性的對象是在故事板中創建的UIViewController,因此您可以在幾個不同的位置執行此操作。您可以覆蓋initWithCoder:awakeFromNibviewDidLoad

如果覆蓋initWithCoder:,則必須調用super方法。

如果你在viewDidLoad中這樣做,直到加載視圖時纔會創建數組,這不一定要馬上發生。

我建議在awakeFromNib做:

@synthesize myArray = _myArray; 

- (void)awakeFromNib { 
    _myArray = [[NSMutableArray alloc] init]; 
} 

另一種選擇是僅通過重寫屬性的getter方法創建數組懶洋洋地:

@synthesize myArray = _myArray; 

- (NSMutableArray *)myArray { 
    if (!_myArray) 
     _myArray = [[NSMutableArray alloc] init]; 
    return _myArray; 
} 

如果你這樣做,這是非常重要的是,您始終使用getter方法(self.myArray[self myArray])訪問陣列,並且決不要直接訪問實例變量(_myArray)。

+0

感謝羅布,看起來像-awakeFromNib是最好的地方,因爲儘管-initWithCoder被調用,如果我實現它並做'if([self = super] init])'我的協議方法因某種原因而被調用。 init中的-awakeFromNib工作得很好。 – TijuanaKez 2012-02-20 08:00:08

+0

在附註上,xcode始終將initWithNibName:bundle:方法添加到我的所有uiviewcontroller子類中,但是方法從未在任何子類中調用過。爲什麼它在那裏,它是安全的刪除它? – TijuanaKez 2012-04-02 03:50:10

+0

如果以編程方式創建視圖控制器,則可以將初始化代碼添加到該方法。由於您正在故事板中創建視圖控制器,因此可以刪除虛擬方法。它只是Xcode用於UIViewController的新子類的標準模板的一部分。 – 2012-04-02 04:37:47

2

這裏是你的代碼需要什麼:

@interface BlahBlah : UIViewController 
@property (...) NSMutableArray *myArray; 
@end 

起初,*myArray只是一個指針是等於零。您不能將其用作數組。它需要被設置爲一個有效的NSMutableArray實例。您需要在指定的初始化程序中執行此操作:

@implementation BlahBlah 

@synthesize myArray; 

// -initWithNibName:bundle: is the designated initializer for UIViewController 
- (id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)nibBundle 
{ 
    self = [super initWithNibName:nibName bundle:nibBundle]; 
    if (self) { 
     myArray = [[NSMutableArray alloc] init]; 
     // now you can add objects to myArray 
    } 
    return self; 
} 

- (void)dealloc 
{ 
    [myArray release]; 
    [super dealloc]; 
} 

請注意,您不能僅覆蓋-init;你必須重寫你的類的指定初始化器。找出你正在實現的子類,找出它指定的初始化方法是什麼,重寫它(但是通常需要調用超類實現),然後初始化你的屬性。

這是Apple documentation regarding multiple/designated initializers

+2

這是很常見的錯誤。記得初始化你的數組! – Daniel 2012-02-20 06:56:05

+0

它是UIViewController的一個子類(採用UITableViewDelegate和UITableViewDataSource協議)。 Xcode在我的類實現中沒有創建任何init方法。我嘗試覆蓋-init手動,但它永遠不會被調用。看看我的項目中的其他一些UITableView子類,有些具有-initWithNibName:bundle:所以我試圖複製該方法,但它永遠不會被調用。我應該在UIViewController子類中自定義inits? – TijuanaKez 2012-02-20 07:02:50

+0

從UIViewController文檔中,指定的初始化程序是' - (id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)nibBundle'。我在我的答案中更新了這一點,但我沒有對它進行測試。 – bneely 2012-02-20 07:06:45

0

@synthesis也沒有做分配。所以分配並初始化你的數組。那麼它應該工作。

+0

alloc和初始化在viewDidLoad – Aaron 2012-02-20 07:12:45