开发者

Changing number of different UITableViewCells with particular order like Calendar app

Sorry for the long title. In essence, I want to accomplish the same thing that the Calendar app does for Event details. The first cell shows the title and date of the event. The second shows an alert, if 开发者_开发问答there is one, otherwise Notes, if there are any, or nothing else if none of these fields is present.

The way I am doing it now is a really long if condition in 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

That's really ugly, and since I create the cells in the if and return, the static analyzer tell me that each one of those is a potential leak. There is no else, since I need to cover all scenarios anyway, and that also gives a warning about the method potentially not returning anything.

Is there a better way that makes this cleaner and doesn't give me warnings?

Thanks!

Christoph


The warning are because you are leaking memory, you have to autorelease the cell: TitleCell *titlecell = [[[TitleCell alloc] init] autorelease];. Also there is a chance of not having a return statement because you don't have else in your if block.

Here is another way of doing it:


// 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;
}
...

EDIT: fixed as per @Christoph's comment


Clang is right when it says that you're leaking memory - The UITableView retains the UITableViewCells that you give it, so you should be autoreleasing them in cellForRowAtIndexPath.

Instead of using if statments, I think you should be using a switch.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜