这是一个错误还是这里有一个微妙的教训?
NSNumber *someNumber = @(1);
[someNumber respondsToSelector:@selector(mutableCopy)]; // returns YES (!)
[someNumber respondsToSelector:@selector(mutableCopyWithZone:)]; // returns NO
Apple LLVM 7.1(iOS SDK 9.3)
答案 0 :(得分:5)
这是因为NSObject
本身通过调用-mutableCopy
来实现NSCopying
(对于所有对象,即使是那些不符合NSMutableCopying
或-mutableCopyWithZone:
的对象) (以便实现NSMutableCopying
的内容只需实现-mutableCopyWithZone:
而无需重复-mutableCopy
)的实现。
从NSObject
继承的所有内容都会响应-mutableCopy
,但如果您实际调用它,则会崩溃,因为NSNumber
不响应-mutableCopyWithZone:
。
你可以用
看到这个assert([NSObject instanceMethodForSelector:@selector(mutableCopy)] == [NSNumber instanceMethodForSelector:@selector(mutableCopy)])
bbum的分析很好地总结了这一点 - 在动态进行这些检查时会有一些微妙的边缘情况,因为你可能得到的答案根本不是你想要的。
答案 1 :(得分:4)
这很奇怪。我不希望该课程实施-mutableCopy
。可能是标记指针实现的后果(如果是这样,那么@(REALLYBIGNUMBERTHATISNEARMAX)会改变行为)。
微妙的教训是,您无法真正使用respondsToSelector:
进行通用功能测试。你也不能使用isKindOfClass:
。在很多情况下它会失败(例如NSArray
与NSMutableArray
表现得非常奇怪 - 可能仍然 - 在尝试使用内省来确定可变性时。“
Introspection适用于明确声明的情况,例如委托或数据源。有@protocol
声明的地方专门定义了一组@optional
方法。