使用日历应用程序等特定顺序更改不同UITableViewCell的数量

时间:2010-10-10 04:44:33

标签: iphone uitableview

很抱歉这个长标题。从本质上讲,我想完成日历应用程序为事件详细信息所做的事情。 第一个单元格显示事件的标题和日期。第二个显示警报(如果有),否则显示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

2 个答案:

答案 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声明。