很抱歉这个长标题。从本质上讲,我想完成日历应用程序为事件详细信息所做的事情。 第一个单元格显示事件的标题和日期。第二个显示警报(如果有),否则显示Notes,如果有,或者如果没有这些字段则不显示。
我现在这样做的方式是在cellForRowAtIndexPath中有一个非常长的条件:
if(indexPath.row == 0) {
TitleCell *titlecell = [[TitleCell alloc] init];
// config cell to do title here, always
return titlecell;
} else if (indexPath.row == 1 && foo) {
FooCell *foocell = [[FooCell alloc] init];
// config cell to show foo, if it exists
return foocell;
} else if (indexPath.row == 1 && bar) {
BarCell *barcell = [[BarCell alloc] init];
// foo doesn't exist, but bar, so show bar in cell 1
return barcell;
} // etc etc
那真是太丑了,因为我在if和return中创建了单元格,静态分析器告诉我每一个都是潜在的泄漏。没有别的,因为无论如何我需要涵盖所有场景,并且还会警告该方法可能不会返回任何内容。
是否有一种更好的方法可以使它更清洁并且不会给我警告?
谢谢!
了Christoph
答案 0 :(得分:2)
警告是因为 泄漏内存,您必须自动释放单元格:TitleCell *titlecell = [[[TitleCell alloc] init] autorelease];
。此外,由于您的else
区块中没有if
,因此可能没有退货声明。
以下是另一种方法:
// Call this beforehand
- (void)loadTable {
// Since we are not using objects, we need to use a non-retaining array
// A better way of doing this would be with delegates or NSInvocations
array = (NSMutableArray*)CFArrayCreateMutable(NULL, 0, NULL);
[array addObject:(id)@selector(buildTitleCell)];
if (foo)
[array addObject:(id)@selector(buildFooCell)];
if (bar)
[array addObject:(id)@selector(buildBarCell)];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row < array.count) {
SEL selector = (SEL)[array objectAtIndex:indexPath.row];
return [self performSelector:selector];
}
return nil;
}
- (UITableViewCell*)buildTitleCell {
TitleCell *titlecell = [[[TitleCell alloc] init] autorelease];
// config cell to do title here, always
return titlecell;
}
...
编辑:根据@Christoph的评论修复
答案 1 :(得分:1)
当它说你正在泄露记忆时,Clang是对的 - UITableView
保留你提供的UITableViewCell
,所以你应该在cellForRowAtIndexPath
中自动释放它们。
我认为你应该使用if
,而不是使用switch
声明。