【问题标题】:Objective-C property access: unrecognized selector sent to instanceObjective-C 属性访问:发送到实例的无法识别的选择器
【发布时间】:2012-11-01 17:18:22
【问题描述】:

我是 Objective-c 的新手,但已经编码多年了。不知何故,我对 Objective-C 不感冒。我搜索了谷歌和stackoverflow,但我认为我的问题只是简单而愚蠢,没有人问过这个问题。

我的代码基于 DateSelectionTitles 示例。 http://developer.apple.com/library/ios/#samplecode/DateSectionTitles/Introduction/Intro.html

我有一个 NSManagedObject

@interface Event : NSManagedObject

@property (nonatomic, retain) NSDate * date;
...

// Cache
@property (nonatomic, retain) NSString * primitiveSectionIdentifier;

所有属性都在我的数据模型中定义,除了primitiveSectionIdentifier(如苹果示例)

但是当我打电话时

NSString *tmp = [self primitiveSectionIdentifier];

我得到了异常

由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“-[Event originalSectionIdentifier]: unrecognized selector sent to instance 0x74850c0”

简单来说:

Event *foo = [[Event alloc] init];

if (foo.primitiveSectionIdentifier) {
    NSLog(@"YEAH");
}

抛出相同的异常。所以我基本上想检查primitiveSectionIdentifier是否为零。但是当我访问该属性时,它会引发异常吗?我是否需要先分配每个属性才能检查它是否有值?!

我没有了解哪些 Objective-C 基础知识?

非常感谢您的回复!

【问题讨论】:

  • 你在@implementation部分写过@synthesize primitiveSectionIdentifier;吗?
  • 你的代码编译时没有警告吗?
  • 如果您使用的是 Xcode 4.5 编译器不会给出未合成的警告(@synthesize 属性)。尝试改用 self.primitiveSectionIdentifier。 Xcode 4.5 发行说明中提到developer.apple.com/library/mac/#releasenotes/DeveloperTools/…

标签: iphone objective-c ios


【解决方案1】:

只有一种方法可以在没有编译器警告的情况下发生这种情况 - 您必须在实现文件中写入 @dynamic primitiveSectionIdentifier;。这意味着您不想定义该方法,因为您认为它已在其他地方定义。

您使用的是NSManagedObject,您知道它是如何工作的吗?您声明没有实现的方法(将@dynamic 放入实现中),当调用该方法时,找不到它,而是调用了一个特殊的处理程序[NSObject doesNotRecognizeSelector:]。此处理程序检查 Core Data 模型是否存在给定选择器的属性,如果不存在,则抛出您看到的异常。

因此,问题可能是由于您的模型中未声明 primitiveSectionIdentifier 造成的。

【讨论】:

  • 谢谢,成功了。我使用了综合原语SectionIdentifier;它奏效了。我认为在 XCode 4 中,合成是自动完成的。如果为属性设置了动态,显然不会。
  • 这正是我的情况,但问题属性实际上是在我的模型中声明的。我能做什么?
  • @Sulthan:感谢您的洞察力。但是,在我的例子中,要访问的属性是在我的模型中定义的,但我还没有在属性中存储任何数据。我使用的是 iOS 9.2。
【解决方案2】:

您正在使用一个较旧的示例程序,它使用不同的内存管理方式;如果您是在 iOS 5 或 6 下编译,则可能会导致问题。

试试

NSLog(@"primitiveSectionIdentifier = %@", self.primitiveSectionIdentifier);

如果它没有为您提供您正在寻找的字符串,那么问题可能在于该字符串对象从未初始化并且仍然设置为 nil。在这种情况下,代码会编译,但是将选择器发送到 nil 指针会引发异常。

【讨论】:

  • nil 发送选择器永远不会抛出异常。这也与内存管理无关。 MRC 仍然有效并被广泛使用。
猜你喜欢
  • 1970-01-01
  • 2014-08-03
  • 1970-01-01
  • 1970-01-01
  • 2023-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-28
相关资源
最近更新 更多