iPhone-C自问

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

在一个简单的UITableView中,我有:

- (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
来说可能没有什么区别,但对很多人来说都会有区别