UITableViewCell错误 - 此类不符合键值编码的关键。

8
当我尝试通过UINib的instantiateWithOwner方法从xib文件中加载自定义的UITableViewCell时,出现以下错误。我已经尝试了这里找到的所有其他解决方案,但都没有成功。问题似乎在于当UINib打开xib文件时,它使用超类UITableViewCell而不是我的自定义类ContentPackCell。我已经附上了一个来自Interface Builder的屏幕截图,显示了我将xib与我的类以及标识符相关联的位置。一定有些步骤我遗漏了。
错误信息:
*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[ setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key descriptionLabel.'
代码(类似于苹果的示例AdvancedTableViewCells项目):
ContentPackCell *cell = (ContentPackCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
    [self.cellNib instantiateWithOwner:self options:nil];
    cell = tmpCell;
    self.tmpCell = nil;
}

在IB中设置自定义类

在IB中设置标识符


更新:

为文件所有者设置类


我已经准备好放弃这个,回到使用 NSBundle 的 loadNibNamed 方法的旧方式。对于我的情况来说,它似乎完全可以工作。 - sam2themax
我发现如果我右键单击自定义单元格标签并拖动到适当的.h文件中创建一个插座,该插座将被分配给文件所有者,这会导致上述崩溃。相反,如果我右键单击标签并将其拖动到表格单元格(向左),然后选择适当的插座,则一切正常。 - Nick T
@softwareevolved 同意,那看起来是一个更好的答案。我还没有回去尝试它,但我已经投票将我的问题关闭为那个的重复。谢谢! - sam2themax
7个回答

37

确保nib文件中的文件所有者设置为NSObject,并确保没有将任何outlets与文件所有者连接。


2
经过查阅大量相关问题,这个解决了我的问题。 - Bo.
1
我也解决了。谢谢。 - Klian
我确认了。破损的IBOutlets是问题所在。 - Claus
1
是的,自定义类必须仅针对单元格指定,而不是文件所有者。之后,进行插座引用。 - sgelves

5

检查你的 Nib 文件中所有的元素,确保它们没有引用不再存在的内容。右键单击它们,查看指向了什么。肯定会发现问题所在。


我不这么认为。问题出在一个指向现有 IBOutlet 的链接上,即 descriptionLabel。问题似乎是 instantiateWithOwner 正在使用 UITableViewCell 而不是我的自定义类。由于 UITableViewCell 中没有针对 descriptionLabel 的 IBOutlet,因此它会崩溃。如果我删除与我的自定义类的 descriptionLabel 的连接,则它不会崩溃,但也没有必要的连接。 - sam2themax

2

看起来你在nib文件中连接了一个UILabel和一个IBOutlet,但是这个IBOutlet在你的代码中已经不存在了(descriptionLabel)。

所以请再次检查你的nib文件。我也多次遇到过此错误,并且这是我的解决方案。


不,看看我对SimonH答案的评论。 - sam2themax

1
我遇到了完全相同的错误,而且当我在左侧的“对象”中右键单击表格单元时,我的.h文件中的IBOutlets没有显示出来,但只有在File's Owner中才会显示。后来我发现,当我在xib文件的“视图”中左键单击自定义表格单元,然后在属性检查器中将其分配给正确的自定义(tableViewCell)类别的“标识符”,就可以在“对象”中看到表格单元上的输出了。也许这可以帮到你!

1
在我的情况下,问题是通过检查可编译源列表中是否存在 .m 来解决的。
如果您重命名、移动或添加自定义表格单元(或 Interface Builder 所需的任何其他内容)的新源文件,则应将它们添加到“项目”->“目标”->“Build Phases”->“Compile Sources”。
如果您有多个目标,请检查所有目标。在我的项目中,有一个活动目标类型为 Aggregate(带有自定义 IPA 构建脚本),我认为这是问题的根源,因为新添加的 *.m 文件缺少 Application 类型目标的 Compile Sources 列表。

感谢您的评论。由于某种原因,XCode未能将我的自定义单元格之一的.m文件添加到构建目标中,尽管通常在我添加新类时会这样做。这为我解决了这个问题。我可能不会想到查看这个作为潜在原因。 - mnemia

0

你试过这样吗?

ContentPackCell *cell = (ContentPackCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
  [self.cellNib instantiateWithOwner:nil options:nil]; //Make owner nil
  cell = tmpCell;
  self.tmpCell = nil;
}

通常当你执行[[NSBundle mainBundle] loadNibNamed:@"ContentPackCell" owner:nil options:nil];时,你会得到像现在这样的错误。所以如果你得到了类似于“此类不符合键值编码”的错误,在这两种情况下,原因都是自定义单元格的“文件所有者”没有设置类。

是的,当我尝试这种方式时,我也遇到了相同的错误,所以我认为你说的有道理--谢谢。不幸的是,我进行了双重检查,并且该类已设置为单元格的文件所有者。我更新了我的问题,并附上了一个截图显示这一点。 - sam2themax

0
static NSString *CellIdentifier = @"CellIdentifierName";
ContentPackCell *cell = (ContentPackCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell == nil) {
    [[NSBundle mainBundle] loadNibNamed:@"ContentPackCell" owner:self options:nil] ;
    cell=objCustomCell;
}

我正在尝试以新的、更高效的方式重用UINib实例来完成一些操作。所以,我不想使用loadNibNamed方法,而是想使用instantiateWithOwner方法。 - sam2themax

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接