2012-02-20 89 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