- [NSObject isMemberOfClass:]方法有用吗?

Coo*_*coa 10 cocoa objective-c

这是我写的一个小测试程序:

#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;
}  
Run Code Online (Sandbox Code Playgroud)

它的输出:

$ ./ismemberof   
Arr isMemberOfClass NSArray: 0   
Arr isKindOfClass NSArray: 1   
Run Code Online (Sandbox Code Playgroud)

-isMemberOfClass:任何Foundation类中的方法有用吗?我理解这可能会为我子类的类提供所需的结果,但对于基础类 - 我发现我的arr变量的结果是非直观的.之所以会发生这种情况,是因为NSArray不是一个具体的类,而是一个抽象类,并且在引擎盖下NSArray实际上是NSCFArray的具体实例?

Pet*_*sey 26

你通常想要isKindOfClass:,而不是isMemberOfClass:.不同的是,isKindOfClass:将返回YES如果接收机是有问题的类的子类的一个成员,而isMemberOfClass:将返回NO在相同的情况下.

正如格雷厄姆·李指出的那样,NSArray是一个阶级集群.这意味着每个NSArray实例实际上都是某个子类的实例 - 因此您的发现.仅对isKindOfClass:类集群的类成员测试有用.

也就是说,您通常应该使用respondsToSelector:而不是类成员测试.一个例子是objectEnumerator,它也是由(NSSetNSDictionary两个也是类集群)实现的.一个例外是plist序列化:集合不是属性列表,因此allObjects在尝试从中生成plist数据之前,您需要发送到您的集合以获取数组.


Sti*_*set 17

当您在自己的类中实现-isEqual:方法时,-isMemberOfClass:非常有用.如果您有这样的课程:

@interface Person : NSObject {
    NSString *name;
    NSUInteger age;
}
@property(copy) NSString *name;
@property(assign) NSUInteger age;
@end
Run Code Online (Sandbox Code Playgroud)

并且如果两个Person对象具有相同的名称和年龄,则需要将它们视为相同,您必须实现-isEqual:,以及来自NSObject:protocol的-hash方法:

- (BOOL)isEqual:(id)obj {
    return [obj isMemberOfClass:[self class]]
        && [obj name] == self.name
        && [obj age] == self.age;
}

- (NSUInteger)hash {
    return [self.name hash] + age;
}
Run Code Online (Sandbox Code Playgroud)

PS:为什么使用[obj isMemberOfClass:[self class]]而不是简单[obj class] == [self class]?它在上面的代码中并不重要,但是当你处理使用NSProxy的更复杂的代码时它变得很重要.isMemberOfClass:方法将询问代理所代表的对象,如果是该类的成员,这可能是您想要的.

  • 投票,因为你实际上回答了这个问题.(VS仅提供有关该主题的相关信息) (4认同)

小智 2

我自己从未使用过 -isMemberOfClass: ,因为如果我向现有类添加功能,通常是通过添加方法来实现的,所以 -respondsToSelector: 已经给了我所需的东西。另一方面,我可以看到想要知道您正在查看哪个特定类(实例)可能是有用的。例如,如果您正在处理 NSConstantString 或 NSSimpleCString,您可能比处理其他类的实例更愿意对 -fastestEncoding 做出假设。

要回答身体中的问题,是的,你是对的。NSArray 是作为类簇实现的,因此您不会看到isMemberOfClass: [NSArray class]. 这并不意味着 -isMemberOfClass: 毫无意义,它只是意味着它对于 NSArray 来说永远不是真的。