Cocoa 插座行为异常,无法识别选择器

Cocoa Outlets acting wierd, won't recognize selector

我遇到了一些奇怪的行为,我在 Interface Builder 中设置了一个标签,然后我将该标签连接到一个文件作为引用插座。

@property (weak) IBOutlet NSTextField *TitleLabel;

当我访问文件中的那个标签(cell.TitleLabel.stringValue = 标题)和 运行 应用程序时,它无法识别 it.I 得到这个:

-[NSApplication TitleLabel]: unrecognized selector sent to instance 0x608000101680

奇怪的是它并不总是这样做,有时它可以正常工作并正确显示,有时则不能。

我刚开始接触 IB,所以我可能遗漏了一些东西。有帮助吗?

属性 真的在您的 NSApplication 子 class 上吗?还是在您的应用程序委托 class 上?它不是不可能它在应用程序对象上,但它会是一个非常不常见的(并且可以说是不明智的)模式。

简而言之,我怀疑您可能将它连接到错误的对象。

编辑:啊。我懂了。您试图通过 topLevelObjects 数组访问内容,但实际上,您不能指望 topLevelObjects 的顺序。您需要依赖 owner 的网点得到填充,但您正在为 owner 传递 niltopLevelObjects 的存在只是为了给 xib 中的顶级对象的调用者 "ownership"(在引用计数意义上)用于内存管理目的,它并不意味着直接 "used"你在这里做。 (公平地说,我可以想象您可能需要自省该数组的情况,但这很难上升到那个级别。)

执行此操作的规范方法是使用 NSViewController subclass 作为所有者。在 Xcode 中,如果您将 NSViewController 的子 class 添加到您的项目中,它将为您提供同时创建一个 xib 文件的选项,该文件将连接所有内容。然后你只需在运行时初始化 NSViewController subclass 并且 class 的 view outlet 属性 将被根视图填充。您显然可以添加更多插座并插入任何您喜欢的东西。

This post appears to cover the basics, if your looking for more details. Apple's docs on xib files and how they work are here.

问题是 View 有时会被分配给 NSApplication。我不确定我启动视图的方式是否是常用的方式,但问题出在这段代码中:

NSArray * views;
[[NSBundle mainBundle] loadNibNamed:@"CollapseClickViewController" owner:nil topLevelObjects:&views];
CollapseClickCell * cell = [[CollapseClickCell alloc] initWithFrame:CGRectMake(0,0,320,50)];
cell = [views objectAtIndex:0];

问题是 [views objectAtIndex:0] 有时 return NSApplication。为了修复它,我只是检查了 class 自身并通过 returned 那个对象:

-(CollapseClickCell*)assignCell:(CollapseClickCell*)cell withArray:(NSArray*)array{
for ( int i = 0; i< [array count]; i++) {
    if ([[array objectAtIndex:i] class] == [CollapseClickCell class]) {
        return [array objectAtIndex:i];
    }
}
return nil;

}

然后我将其分配给对象: cell = [cell assignCell:cell withArray:views];

这可能不是传统的做法,但确实有效。如果有更好的技术或更通用的方法请赐教! :)