2

Here is explanation
List of class properties in Objective-C
how to use class_copyPropertyList to get at runtime all properties of class.

I have tested this and it is working fine.
I have notice that it will only get properties from that class only, and not it subclass.

CODE:

@interface JustForThisUT : NSObject
@property NSUInteger public_access;
@end

@interface JustForThisUT ()
@property NSUInteger private_access;
@end

@implementation JustForThisUT
@end



@interface JustForThisUTParent : JustForThisUT
@property NSUInteger my_public_access;
@end

@interface JustForThisUTParent ()
@property NSUInteger my_private_access;
@end

@implementation JustForThisUTParent
@end

If I use it on JustForThisUT I will get 2 properties (public_access & private_access)
If I use it on JustForThisUTParent I will ALSO get 2 properties (my_public_access & my_private_access)

But for JustForThisUTParent I was expecting to get 4, 2 from JustForThisUT and 2 from JustForThisUTParent.

My question is
How to get properties from current class and all subclasses ?
Is it even possible ?

Community
  • 1
  • 1
WebOrCode
  • 6,852
  • 9
  • 43
  • 70
  • Your question says “subclass” but your code and your expected result suggest that you mean “superclass”. Are you sure you asked this question correctly? – rob mayoff Sep 18 '14 at 15:34
  • @rob best would be to have it for subclass and superclass. But anyway I have decided to solve that problem – WebOrCode Sep 22 '14 at 11:57

2 Answers2

4

You have to first find all the subclasses, then use the class_copyPropertyList() to list the properties for each class, uniquing as needed.

However, this has a bad code smell. This level of dynamic, reflection heavy, programming is counter to what ObjC is really designed for. You'll end up with a fragile codebase that is difficult to maintain.

If you really want dynamism of this nature, then implement a class method on each class that returns the list of property names that you want to be able to dynamically access.

bbum
  • 162,346
  • 23
  • 271
  • 359
  • @bbun you have describe pseudo code of it, and it is correct, my thinking exactly. I was hoping for some code example. Do you know how to `find all the subclasses` of class ? – WebOrCode Aug 30 '14 at 18:46
  • @WebOrCode You have to enumerate all the classes in the runtime, then use `isKindOfClass:`. But, again, you are far *far* better off having a class method that returns a collection of all classes and/or properties that you want to muck with dynamically. – bbum Aug 31 '14 at 21:37
  • @bbun I have found some code example here.: http://stackoverflow.com/questions/7923586/objective-c-get-list-of-subclasses-from-superclass but I have not tested it. I will accept yop answer, for now. Thanks on your help. – WebOrCode Sep 01 '14 at 08:32
1

It's fairly simple to find all the superclasses (I presume this is what you meant, rather than subclasses); you simply loop until class.superclass == NSObject.class.

Do note @bbum's comments about this being a bad code smell though. Read his answer and consider alternative approaches, and really think about why you want to do this and if there's a better way.

That said, here's a full code example that retrieves all the BOOL properties from a class. It would be easy to extend it for other property types - see the linked questions.

/**
 * Get a name for an Objective C property
 *
 */
- (NSString *)propertyTypeStringOfProperty:(objc_property_t) property {
    NSString *attributes = @(property_getAttributes(property));

    if ([attributes characterAtIndex:0] != 'T')
        return nil;

    switch ([attributes characterAtIndex:1])
    {
        case 'B':
            return @"BOOL";
    }

    assert(!"Unimplemented attribute type");
    return nil;
}

/**
 * Get a name->type mapping for an Objective C class
 *
 * Loosely based on http://stackoverflow.com/questions/754824/get-an-object-properties-list-in-objective-c
 *
 * See 'Objective-C Runtime Programming Guide', 'Declared Properties' and
 * 'Type Encodings':
 *   https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtPropertyIntrospection.html#//apple_ref/doc/uid/TP40008048-CH101
 *   https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html#//apple_ref/doc/uid/TP40008048-CH100-SW1
 *
 * @returns (NSString) Dictionary of property name --> type
 */

- (NSDictionary *)propertyTypeDictionaryOfClass:(Class)klass {
    NSMutableDictionary *propertyMap = [NSMutableDictionary dictionary];
    unsigned int outCount, i;
    objc_property_t *properties = class_copyPropertyList(klass, &outCount);
    for(i = 0; i < outCount; i++) {
        objc_property_t property = properties[i];
        const char *propName = property_getName(property);
        if(propName)
        {
            propertyMap[@(propName)] = [self propertyTypeStringOfProperty:property];
        }
    }
    free(properties);
    return propertyMap;
}

- (NSDictionary *)settingsProperties
{
    if (!_settingsProperties)
    {
        Class class = _settings.class;
        NSMutableDictionary *propertyMap = [[NSMutableDictionary alloc] init];

        do
        {
            [propertyMap addEntriesFromDictionary:[self propertyTypeDictionaryOfClass:class]];
        }
        while ((class = class.superclass) != NSObject.class);

        _settingsProperties = propertyMap;
    }

    return _settingsProperties;
}
JosephH
  • 37,173
  • 19
  • 130
  • 154
  • You cannot find subclasses by accessing the superclass. Really, you can't. – Sulthan Apr 04 '17 at 10:21
  • @sulthan Ah, thanks, I've fixed that. The question uses the word 'subclass' when (from the example) he clearly means superclass. I'd copied the error and accidentally used subclass when I meant superclass, now fixed. – JosephH Apr 04 '17 at 11:39
  • I would edit that but that would change the meaning of the accepted answer. It's a bad question. – Sulthan Apr 04 '17 at 11:44