iPhone-C自问
在一个简单的UITableView中,我有:iPhone-C自问,iphone,objective-c,Iphone,Objective C,在一个简单的UITableView中,我有: - (void)viewDidLoad { NSArray *array = [[NSArray alloc]initWithObjects:@"Pictures",@"Video",@"Text",@"Map",nil]; self.selectionList = array; [array release]; [super viewDidLoad]; } ... - (UITableViewCell *)tableView:(U
- (void)viewDidLoad {
NSArray *array = [[NSArray alloc]initWithObjects:@"Pictures",@"Video",@"Text",@"Map",nil];
self.selectionList = array;
[array release];
[super viewDidLoad];
}
...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
NSUInteger row = [indexPath row];
cell.textLabel.text = [selectionList objectAtIndex:row];
return cell;
}
我的问题是,为什么在viewDidLoad部分中,它需要是self.selectionList而不仅仅是selectionList??我的意思是,关键是将我们刚刚创建的数组的内容传递到selectionList数组中,那么为什么是self呢?这里的区别在于内存管理的工作方式。假设
@属性
selectionList定义为retain,调用self.selectionList=something
隐式调用[selectionList retain]
在这个特定的示例中,只需执行
selectionList=something代码>很可能会导致线路崩溃,因为对象正在释放。这里的区别在于内存管理的工作方式。假设@属性
selectionList定义为retain,调用self.selectionList=something
隐式调用[selectionList retain]
在这个特定的示例中,只需执行selectionList=something代码>很可能会导致行崩溃,因为对象正在被释放。无论何时使用“self”,它都将使用属性setter和getter。这意味着,如果您将属性创建为保留,它将允许您释放
(setter将调用保留
)。如果没有使用setter(我假设它是一个retain属性),也可以这样编写上面的内容(但我不推荐):
无论何时使用“self”,它都将使用属性setter和getter。这意味着,如果您将属性创建为保留,它将允许您释放
(setter将调用保留
)。如果没有使用setter(我假设它是一个retain属性),也可以这样编写上面的内容(但我不推荐):
在本例中,它需要是self.selectionList,因为这使用的是setter方法(我假定您在头中使用了带有retain属性的属性,然后在实现中合成了selectionList)。这实际上和做
[self setSelectionList:array];
…如果有道理的话
否则,您只需将数组分配给一个类实例变量,并且需要执行retain和后续版本以确保正确管理它。在这个实例中,它需要是self.selectionList,因为这是使用setter方法的(我假设您在标题中使用了带有retain属性的属性,然后在实现中合成了selectionList)
[self setSelectionList:array];
…如果有道理的话
否则,您只需将数组分配给一个类实例变量,并且需要执行retain和后续版本,以确保正确管理该数组。因为self.selectionList使用属性(->setter方法)而不是直接访问实例变量。这使得在子类中覆盖此变量访问成为可能,而直接ivar访问是不可能的。使用属性通常是更干净的方法(数据封装/信息隐藏)
如其他注释中所述:如果没有该属性,您必须在设置ivar的每一点上关注内存管理。在这种情况下,什么才是您必须放弃该版本的正确含义。因为self.selectionList使用属性(->setter方法)而不是直接访问实例变量。这使得在子类中覆盖此变量访问成为可能,而直接ivar访问是不可能的。使用属性通常是更干净的方法(数据封装/信息隐藏)
如其他注释中所述:如果没有该属性,您必须在设置ivar的每一点上关心内存管理。在这种情况下,什么才是您必须放弃发布的正确含义。使用点语法(最有可能)ratain
ing或copy
ing属性有三种效果:它分配或复制数组(取决于声明),确保它获得一条保留消息,使其保持活动状态,并且-同样重要的是-release
s旧数组,使其不会泄漏
如果不想使用点语法,则必须手动执行所有这些步骤。将点语法用于(很可能)ratain
ing或copy
ing属性有三种效果:它分配或复制数组(取决于声明),确保它获得一条保留消息,这样它将保持活动状态,并且-同样重要的是-释放
s旧数组,这样它就不会泄漏
如果不想使用点语法,则必须手动执行所有这些步骤。阅读属性和Objective-C内存管理旁注:viewDidLoad
应首先使用父调用(作为第一行)@Kevin:不应该有什么区别-在苹果的文档中,它通常被称为“完全没有”。@Eiko我认为,在任何先做初始化的事情上都叫super,在任何最后做销毁的事情上都叫super是一个相当普遍的惯例。这对viewDidLoad
可能没有什么区别,但对许多其他类似的调用都会有影响。谢谢大家或者所有的帮助,我希望我能说我完全理解你的所有解释,但我对所有这些仍然有点模糊。事实上,我知道这是一个setter/getter和内存管理问题,至少我对正在发生的事情有一个粗略的概念。阅读属性和Objective-C内存管理旁注:viewDidLoad
应该首先有父调用(作为第一行)@Kevin:不应该有什么区别-在苹果的文档中,它通常被称为“完全没有”。@Eiko我认为,在任何首先进行初始化的事情上,它都会被称为“超级”,在任何最后进行销毁的事情上,它都会被称为“超级”。这对viewDidLoad
来说可能没有什么区别,但对很多人来说都会有区别