NSNumber 正面回应 mutableCopy?

NSNumber responds positively to mutableCopy?

这是一个错误还是这里有一个微妙的教训?

NSNumber *someNumber = @(1);
[someNumber respondsToSelector:@selector(mutableCopy)]; // returns YES (!)
[someNumber respondsToSelector:@selector(mutableCopyWithZone:)]; // returns NO

Apple LLVM 7.1(iOS SDK 9.3)

真奇怪。我不希望 class 实现 -mutableCopy。可能是标记指针实现的后果(如果是这样,那么 @(REALLYBIGNUMBERTHATIS​​NEARMAX) 会改变行为)。

微妙的教训是您不能真正使用 respondsToSelector: 进行通用功能测试。也不能使用 isKindOfClass:。在许多情况下它会失败(例如,NSArrayNSMutableArray 曾经表现得很奇怪——可能仍然是——当试图使用内省来确定可变性时)。

内省适用于显式声明的情况,例如委派或数据源。有 @protocol 声明的地方专门定义了一些 @optional 方法集。

这是因为 NSObject 本身通过调用 [=15] 实现了 -mutableCopy(对于所有对象,即使是那些不符合 NSCopyingNSMutableCopying 的对象) =](这样实现 NSMutableCopying 的东西就可以实现 -mutableCopyWithZone:,而不需要为 -mutableCopy 重复实现)。

NSObject 继承的所有内容都会响应 -mutableCopy,但如果您实际调用它,它会崩溃,因为 NSNumber 不会响应 -mutableCopyWithZone:

你可以通过

看到这个
assert([NSObject instanceMethodForSelector:@selector(mutableCopy)] == [NSNumber instanceMethodForSelector:@selector(mutableCopy)])

bbum 的分析很好地总结了这一点——动态地进行这些检查时会出现一些微妙的边缘情况,因为您可能会得到完全出乎意料的答案。