How to detect a property return type in Objective-C

后端 未结 6 1739
南旧
南旧 2020-12-05 11:10

I have an object in objective-c at runtime, from which I only know the KVC key and I need to detect the return value type (e.g. I need to know if its an NSArray or NSMutable

相关标签:
6条回答
  • 2020-12-05 11:19

    You can use isKindOfClass message

    if([something isKindOfClass:NSArray.class])
         [somethingElse action];
    
    0 讨论(0)
  • 2020-12-05 11:26

    This is really a comment addressing an issue raised by Greg Maletic in response to answer provided by e.James 21APR09.

    Agreed that Objective-C could use a better implementation for getting these attributes. Below is a method I quickly threw together to retrieve attributes of a single object property:

    - (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;
    }
    

    Partial list of attribute keys:

    • R Read-only
    • C Copy of last value assigned
    • & Reference to last value assigned
    • N Nonatomic property
    • W Weak reference

    Full list at Apple

    0 讨论(0)
  • 2020-12-05 11:27

    You're talking about runtime property introspection, which happens to be something that Objective-C is very good at.

    In the case you describe, I'm assuming you have a class like this:

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

    Which gets encoded in XML something like this:

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

    From this information, you want to recreate the class and also give it an appropriate value for stuff.

    Here's how it might look:

    #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's documentation (linked above) has all of the dirty details about what you can expect to see in propertyAttrs.

    0 讨论(0)
  • 2020-12-05 11:31

    The preferred way is to use the methods defined in the NSObject Protocol.

    Specifically, to determine if something is either an instance of a class or of a subclass of that class, you use -isKindOfClass:. To determine if something is an instance of a particular class, and only that class (ie: not a subclass), use -isMemberOfClass:

    So, for your case, you'd want to do something like this:

    // 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.
    }
    
    0 讨论(0)
  • 2020-12-05 11:33

    Cheap answer: use the NSObject+Properties source here.

    It implements the same methodology described above.

    0 讨论(0)
  • 2020-12-05 11:38

    If you know that the property is defined :

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

    And compare with isKindOfClass, isSubClass, etc.

    0 讨论(0)
提交回复
热议问题