objective-c -[NSObject isMemberOfClass:] 方法有多大用处?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/383978/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How useful is the -[NSObject isMemberOfClass:] method?
提问by Coocoo4Cocoa
Here's a small test program I wrote:
这是我写的一个小测试程序:
#import <Foundation/Foundation.h>
int main(int argc, char **argv) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSArray *arr = [NSArray array];
printf("Arr isMemberOfClass NSArray: %d\n", [arr isMemberOfClass:[NSArray class]]);
printf("Arr isKindOfClass NSArray: %d\n", [arr isKindOfClass:[NSArray class]]);
[pool release];
return 0;
}
And its output:
它的输出:
$ ./ismemberof
Arr isMemberOfClass NSArray: 0
Arr isKindOfClass NSArray: 1
How useful is the -isMemberOfClass:method in any of the Foundation classes? I understand this might give the desired results for classes which I subclass, but as for Foundation classes -- I find that a result of false for my arr variable is non-intuitive. Is the reason this happens because NSArray is not a concrete class but instead an abstract class, and underneath the hood NSArray is really a concrete instance of NSCFArray?
该-isMemberOfClass:方法在任何 Foundation 类中有多有用?我知道这可能会给我子类化的类提供所需的结果,但对于基础类——我发现我的 arr 变量的结果为 false 是不直观的。发生这种情况的原因是不是因为 NSArray 不是一个具体的类而是一个抽象类,而在幕后 NSArray 真的是 NSCFArray 的一个具体实例?
回答by Peter Hosey
You generally want isKindOfClass:, not isMemberOfClass:. The difference is that isKindOfClass:will return YESif the receiver is a member of a subclass of the class in question, whereas isMemberOfClass:will return NOin the same case.
你一般想要isKindOfClass:,不是isMemberOfClass:。不同的是,isKindOfClass:将返回YES如果接收机是有问题的类的子类的一个成员,而isMemberOfClass:将返回NO在相同的情况下。
As Graham Lee points out, NSArrayis a class cluster. That means that every NSArrayinstance is actually an instance of some subclass—hence your findings. Only isKindOfClass:is useful for class-membership testing with class clusters.
正如 Graham Lee 指出的那样,NSArray是一个类簇。这意味着每个NSArray实例实际上都是某个子类的实例——因此您的发现。OnlyisKindOfClass:对类集群的类成员测试有用。
That said, you generally should use respondsToSelector:rather than class-membership testing. One example would be objectEnumerator, which is also implemented by NSSetand NSDictionary(both of those also being class clusters). An exception would be plist serialization: sets aren't property lists, so you'd need to send allObjectsto your set to get an array before trying to make plist data from it.
也就是说,您通常应该使用respondsToSelector:而不是类成员资格测试。一个例子是objectEnumerator,它也是由NSSet和实现的NSDictionary(这两个也是类集群)。plist 序列化是一个例外:集合不是属性列表,因此allObjects在尝试从中生成 plist 数据之前,您需要发送到您的集合以获取数组。
回答by Stig Brautaset
The -isMemberOfClass: is useful when you're implementing the -isEqual:method in your own classes. If you have a class like this:
-isMemberOfClass: 当您-isEqual:在自己的类中实现该方法时非常有用。如果您有这样的课程:
@interface Person : NSObject {
NSString *name;
NSUInteger age;
}
@property(copy) NSString *name;
@property(assign) NSUInteger age;
@end
And you want two Person objects to be deemed identical if they have the same name and age, you have to implement -isEqual:, and the -hashmethod from the NSObjectprotocol:
如果两个 Person 对象具有相同的名称和年龄,您希望它们被视为相同,则必须实现-isEqual:,以及协议中的-hash方法NSObject:
- (BOOL)isEqual:(id)obj {
return [obj isMemberOfClass:[self class]]
&& [obj name] == self.name
&& [obj age] == self.age;
}
- (NSUInteger)hash {
return [self.name hash] + age;
}
PS: why use [obj isMemberOfClass:[self class]]rather than simply [obj class] == [self class]? It doesn't matter much in the code above, but it becomes important when you're dealing with more complex code that makes use of NSProxy. The isMemberOfClass:method will ask the object the proxy is standing in for if itis a member of that class, which is probably what you want.
PS:为什么要使用[obj isMemberOfClass:[self class]]而不是简单的[obj class] == [self class]?在上面的代码中它并不重要,但是当您处理使用NSProxy. 该isMemberOfClass:法将要求代理站在了如果对象是是类,这可能是你想要什么样的一员。
回答by Coocoo4Cocoa
I've never used -isMemberOfClass: myself, because if I've added functionality to an existing class it's usually been through adding methods, so -respondsToSelector: has given me what I need. On the other hand I can see how wanting to know which specific class you're looking at (an instance of) may be useful. For instance if you're dealing with an NSConstantString or NSSimpleCString you may be more willing to make assumptions regarding -fastestEncoding than you might be with instances of other classes.
我从来没有使用过 -isMemberOfClass: 我自己,因为如果我向现有类添加功能通常是通过添加方法,所以 -respondsToSelector: 给了我我需要的东西。另一方面,我可以看到想要知道您正在查看哪个特定类(一个实例)可能很有用。例如,如果您正在处理 NSConstantString 或 NSSimpleCString,您可能更愿意对 -fastestEncoding 做出假设,而不是处理其他类的实例。
To answer the question in the body, yes you're correct. The NSArray is implemented as a class cluster, so you will not see an object which isMemberOfClass: [NSArray class]. That doesn't make -isMemberOfClass: meaningless, it just means it's never true for NSArray.
要回答正文中的问题,是的,您是对的。NSArray 是作为类簇实现的,因此您将看不到isMemberOfClass: [NSArray class]. 这不会使 -isMemberOfClass: 毫无意义,它只是意味着 NSArray 永远不会如此。

