如何设置表视图单元附件视图以保留以前初始化的UIImageView?

Ale*_*lds 7 iphone uitableview uiimageview

假设我的视图控制器中有一个属性,定义如下:

@property (nonatomic, retain) UIImageView *checkmarkOffAccessoryView;
Run Code Online (Sandbox Code Playgroud)

@synthesize在实现中,将release-dealloc初始化并-viewDidLoad如下所示:

self.checkmarkOffAccessoryView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"checkmarkOff.png"]] autorelease];
Run Code Online (Sandbox Code Playgroud)

到现在为止还挺好.

当我在我的表视图委托中使用它作为多个单元格的附件视图时,会发生两件事:

  1. 只有一个单元的附件视图显示图像
  2. 应用程序UI冻结.

该应用程序不会崩溃,因为我可以说,UI只是变得没有响应.这是在模拟器和设备上.

这是我如何使用我的单元格初始化属性:

- (UITableViewCell *) tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    // initialize or dequeue cell...

    if (condition)
        cell.accessoryView = self.checkmarkOffAccessoryView;
    else
        cell.accessoryView = nil;
}
Run Code Online (Sandbox Code Playgroud)

使用上述代码,只有一个单元显示附件视图并且UI冻结.

如果我UIImageView直接在委托方法中初始化实例,我会得到所有满足条件的单元格显示附件视图,并且我没有遇到UI冻结:

- (UITableViewCell *) tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    // initialize or dequeue cell...

    if (condition)
        cell.accessoryView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"checkmarkOff.png"]] autorelease];
    else
        cell.accessoryView = nil;
}
Run Code Online (Sandbox Code Playgroud)

我的目标是初始化尽可能少的对象并重用一个UIImageView.我很好奇为什么第一块代码是有问题的,我可以做些什么来解决这个问题.

似乎单元格的accessoryView属性应该只增加retain计数self.checkmarkOffAccessoryView但看起来我缺少一些细节.

我忽略了什么?谢谢你的建议.

编辑

我觉得:

self.checkmarkOffAccessoryView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"checkmarkOff.png"]] autorelease];
Run Code Online (Sandbox Code Playgroud)

是相同的:

UIImageView *uncheckedView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"checkmarkOff.png"]];
self.checkmarkOffAccessoryView = uncheckedView;
[uncheckedView release];
Run Code Online (Sandbox Code Playgroud)

无论哪种方式,我都会遇到相同的冻结症状.

Kal*_*lle 9

您无法多次添加同一视图.UI处理程序将疯狂.为了确保这一点,我试着按照你上面所说的做,我也遇到了同样的问题.UI冻结,图像仅出现在其中一个单元格中.

你可以做的最好的事情是将你的图像存储为分配的UIImage,并有一个辅助函数,每个单元格返回一个新的UIImageView.

使用您当前的方法(没有存储的UIImage),您可能会:

-(UIImageView *) makeCheckmarkOffAccessoryView
{
    return [[[UIImageView alloc] initWithImage:
        [UIImage imageNamed:@"checkmarkOff.png"]] autorelease];
}
Run Code Online (Sandbox Code Playgroud)

然后呢

cell.accessoryView = [self makeCheckmarkOffAccessoryView];
Run Code Online (Sandbox Code Playgroud)

您可能知道,另一方面,UIImages可能会被使用多次.UIImageView不占用大量空间,因此您可以轻松拥有一堆而不用担心.

为了扩展一个地方的交易,想象你同时在两个地方添加一个UIView.

[ob removeFromSuperview]将为此对象做什么?它会从两个地方删除视图吗?只从他们中的一个?请求[ob superview]时会返回哪个值?很明显,用户界面并不能满足您的要求.


Dan*_*Ray 0

尝试在初始化程序中不使用自动释放。我怀疑你释放过度了。

顺便说一句,您的控制台在冻结时可能会显示 BAD_ACCESS 错误。如果您打开 NSZombieEnabled,我的猜测是您会看到它正在调用已释放的 UIImage。