19

我在运行时在objective-c中有一个对象,从中我只知道KVC键,我需要检测这个属性的返回值类型(例如我需要知道它是NSArray还是NSM​​utableArray),我该怎么做?

4

6 回答 6

34

您说的是运行时属性自省,这恰好是 Objective-C非常擅长的.

在您描述的情况下,我假设您有这样的课程:

@interface MyClass
{
    NSArray * stuff;
}
@property (retain) NSArray * stuff;
@end

它在 XML 中编码,如下所示:

<class>
    <name>MyClass</name>
    <key>stuff</key>
</class>

根据这些信息,您希望重新创建该类并为其赋予适当的stuff.

以下是它的外观:

#import <objc/runtime.h>

// ...

Class objectClass;       // read from XML (equal to MyClass)
NSString * accessorKey;  // read from XML (equals @"stuff")

objc_property_t theProperty =
    class_getProperty(objectClass, accessorKey.UTF8String);

const char * propertyAttrs = property_getAttributes(theProperty);
// at this point, propertyAttrs is equal to: T@"NSArray",&,Vstuff
// thanks to Jason Coco for providing the correct string

// ... code to assign the property based on this information

Apple 的文档(上面链接)包含所有关于您可以在propertyAttrs.

于 2009-04-21T00:09:34.243 回答
17

便宜的答案:在这里使用 NSObject+Properties 源

它实现了与上述相同的方法。

于 2009-05-11T21:40:09.683 回答
4

首选方法是使用NSObject 协议中定义的方法。

具体来说,要确定某物是某个类的实例还是该类的子类的实例,请使用-isKindOfClass:. 要确定某物是否是特定类的实例,并且仅是该类(即:不是子类),请使用-isMemberOfClass:

因此,对于您的情况,您需要执行以下操作:

// Using -isKindOfClass since NSMutableArray subclasses should probably
// be handled by the NSMutableArray code, not the NSArray code
if ([anObject isKindOfClass:NSMutableArray.class]) {
    // Stuff for NSMutableArray here
} else if ([anObject isKindOfClass:NSArray.class]) {
    // Stuff for NSArray here

    // If you know for certain that anObject can only be
    // an NSArray or NSMutableArray, you could of course
    // just make this an else statement.
}
于 2009-04-20T18:20:20.603 回答
2

这实际上是针对 Greg Maletic 为回应 e.James 21APR09 提供的回答而提出的问题的评论。

同意 Objective-C 可以使用更好的实现来获取这些属性。下面是我快速组合起来检索单个对象属性的属性的方法:

- (NSArray*) attributesOfProp:(NSString*)propName ofObj:(id)obj{

    objc_property_t prop = class_getProperty(obj.class, propName.UTF8String);
    if (!prop) {
       // doesn't exist for object
       return nil;
    }
    const char * propAttr = property_getAttributes(prop);
    NSString *propString = [NSString stringWithUTF8String:propAttr];
    NSArray *attrArray = [propString componentsSeparatedByString:@","];
    return attrArray;
}

属性键的部分列表:

  • R 只读
  • C 分配的最后一个值的副本
  • & 引用最后分配的值
  • N 非原子性质
  • W 弱参考

Apple的完整列表

于 2013-05-07T23:01:55.443 回答
1

您可以使用 isKindOfClass 消息

if([something isKindOfClass:NSArray.class])
     [somethingElse action];
于 2009-04-20T17:40:58.637 回答
0

如果您知道该属性已定义:

        id vfk = [object valueForKey:propertyName];
        Class vfkClass = vfk.class;

并与 isKindOfClass、isSubClass 等进行比较。

于 2014-07-15T09:26:48.333 回答