Objective c 目标-C–;使用子视图

Objective c 目标-C–;使用子视图,objective-c,uiview,uitableview,Objective C,Uiview,Uitableview,我有点困惑。我正在对一个UITableViewCell进行子类化,以创建我自己的单元格设计。在-initWithStyle:方法中,我设置了一些UILabels,如下所示: self.careerTitleLabel = [[UILabel alloc] init]; [self.contentView addSubview:careerTitleLabel]; [self.careerTitleLabel release]; 然后在-layoutSubviews中定位标签,如下所示: CGR

我有点困惑。我正在对一个
UITableViewCell
进行子类化,以创建我自己的单元格设计。在
-initWithStyle:
方法中,我设置了一些
UILabel
s,如下所示:

self.careerTitleLabel = [[UILabel alloc] init];
[self.contentView addSubview:careerTitleLabel];
[self.careerTitleLabel release];
然后在
-layoutSubviews
中定位标签,如下所示:

CGRect careerTitleLabelFrame = CGRectMake(10, 10, 280, 20);

self.careerTitleLabel.frame = careerTitleLabelFrame;
这段代码实际上是有效的。它将我的标签定位在我想要的位置。但我不明白的是这是怎么回事。因为我只是在修改careerTitleLabel ivar的框架,而不是作为子视图添加到contentView的careerTitleLabel

我的假设是,要修改添加到contentView的标签框架,我必须使用
-viewWithTag:
将其拉出,然后修改该框架。现在我只是在修改班级的ivar


另一个与这个问题无关的悬念是为什么self.careertletlabel在发布后会有一个2的重新计数?D.S

添加子视图:
不会复制您传递的视图,而是保留它。所以当你释放它时,它实际上并没有被释放。它之所以保持活动状态,是因为
self.contentView
仍在使用它。这意味着您以后对Self.CaleReTeleLabel.的引用仍然有效,但我认为大多数人会认为它是坏的风格,理由是您应该保留对您稍后要传达的任何对象的引用,而不是将知识从其他地方使用的所有权模式中提取出来。
retainCount
绝对不能依赖。它还不清楚
addSubview:
将使保留计数增加多少,除此之外,它将至少增加1。也就是说,如果您将
careerTitleLabel
声明为属性,并且有一行类似于:

NSLog(@"%d", [self.careerTitleLabel retainCount]);
标准的吸气剂是:

return [[careerTitleLabel retain] autorelease];

因此,getter会暂时增加retain计数,原因是getter的结果应该至少与autorelease池一样长——即使在此之前从中获取它们的对象被解除分配。

addSubview:
不会复制您传递的视图,而是保留它。所以当你释放它时,它实际上并没有被释放。它之所以保持活动状态,是因为
self.contentView
仍在使用它。这意味着您以后对Self.CaleReTeleLabel.的引用仍然有效,但我认为大多数人会认为它是坏的风格,理由是您应该保留对您稍后要传达的任何对象的引用,而不是将知识从其他地方使用的所有权模式中提取出来。
retainCount
绝对不能依赖。它还不清楚
addSubview:
将使保留计数增加多少,除此之外,它将至少增加1。也就是说,如果您将
careerTitleLabel
声明为属性,并且有一行类似于:

NSLog(@"%d", [self.careerTitleLabel retainCount]);
标准的吸气剂是:

return [[careerTitleLabel retain] autorelease];

因此,getter会暂时增加retain计数,其原因是getter的结果应该至少与自动释放池一样长——即使在此之前从中获取它们的对象已解除分配。

careertilelabel
是指向对象的指针。因此,当您执行
addSubview:careerTitleLabel
时,您调用的代码将维护对
careertlelabel
的引用

稍后,当您在
layoutSubviews
中的
careertletlabel
上设置框架时,您正在更新同一对象

layoutSubviews
绝对是执行此操作的正确位置。它会在开始时自动调用,如果视图边界发生变化,会再次调用。例如,如果设备的方向发生变化

viewWithTag
是访问子视图的另一种方式。我个人认为保持IVAR更干净。不要忘记,您可以使用IBOutlets使用interfacebuilder连接这些东西

最后,您确实存在内存问题,这解释了保留计数。经常运行Analyze以发现这些问题,并使用泄漏的仪器进行分析是很好的。您甚至可以在生成设置中设置一个标志,以便在每次生成时始终运行分析

无论如何,问题是:

self.careerTitleLabel = [[UILabel alloc] init];
如果.h文件中的属性设置为:

@property (nonatomic, retain)
那你就留在这里。您将保留两次,这将导致内存问题

苹果的指导方针建议你永远不要在init方法中调用这些setter。在那个阶段,行为可能是不可预测的,因为当对象尚未完成初始化时,您可能正在经历一个自定义的setwhater方法

只有以下几点更安全:

    careerTitleLabel = [[UILabel alloc] init];
更好的是,在.h文件中,为成员变量添加前缀“m”。那你就有

    mCareerTitleLabel = [[UILabel alloc] init];
在您的应用程序中,请使用:

    synthesize careerTitleLabel = mCareerTitleLabel;
这意味着从代码外部或内部,您可以通过以下方式访问:

    self.careerTitleLabel


我希望这有帮助!要报道的内容太多了

careertilelabel
是指向对象的指针。因此,当您执行
addSubview:careerTitleLabel
时,您调用的代码将维护对
careertlelabel
的引用

稍后,当您在
layoutSubviews
中的
careertletlabel
上设置框架时,您正在更新同一对象

layoutSubviews
绝对是执行此操作的正确位置。它会在开始时自动调用,如果视图边界发生变化,会再次调用。例如,如果设备的方向发生变化

viewWithTag
是访问子视图的另一种方式。我个人认为保持IVAR更干净。不要忘记,您可以使用IBOutlets使用interfacebuilder连接这些东西

最后,您确实存在内存问题,这解释了保留计数。经常运行Analyze以发现这些问题,并使用泄漏的仪器进行分析是很好的。您甚至可以在生成设置中设置一个标志,以便在每次生成时始终运行分析

不管怎么说,这里没有