Last active
May 22, 2020 06:56
-
-
Save nicked/94bafcfd90c29a58345688bd163901f6 to your computer and use it in GitHub Desktop.
Wrapper for Objective-C runtime property functions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@import Foundation; | |
@import ObjectiveC.runtime; | |
typedef NS_ENUM(char, SetterType) { | |
Assign, Strong, Weak, Copy | |
}; | |
@interface ClassProperty : NSObject | |
@property (nonatomic, readonly) NSString *name; | |
/// This will be the raw type encoding for now | |
@property (nonatomic, readonly) NSString *encodeType; | |
@property (nonatomic, readonly) BOOL isReadOnly; | |
@property (nonatomic, readonly) BOOL isNonAtomic; | |
@property (nonatomic, readonly) BOOL isDynamic; | |
@property (nonatomic, readonly) SetterType setterType; | |
/// Custom getter or the default getter | |
@property (nonatomic, readonly) SEL getter; | |
/// Custom or default setter, NULL if the property is readonly | |
@property (nonatomic, readonly, nullable) SEL setter; | |
/// Will be nil if the property is computed or dynamic | |
@property (nonatomic, readonly, nullable) NSString *ivarName; | |
- (instancetype)initWithProperty:(objc_property_t)property; | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@implementation ClassProperty | |
@synthesize getter = _getter; | |
@synthesize setter = _setter; | |
- (instancetype)initWithProperty:(objc_property_t)property { | |
self = [super init]; | |
if (self) { | |
_name = @(property_getName(property)); | |
_setterType = Assign; // this is the default | |
NSString *attribStr = @(property_getAttributes(property)); | |
NSArray *attribs = [attribStr componentsSeparatedByString:@","]; | |
for (NSString *attrib in attribs) { | |
unichar attribChar = [attrib characterAtIndex:0]; | |
NSString *attribDetail = [attrib substringFromIndex:1]; | |
switch (attribChar) { | |
case 'T': | |
_encodeType = attribDetail; | |
break; | |
case 'R': | |
_isReadOnly = YES; | |
break; | |
case 'N': | |
_isNonAtomic = YES; | |
break; | |
case 'D': | |
_isDynamic = YES; | |
break; | |
case '&': | |
_setterType = Strong; | |
break; | |
case 'W': | |
_setterType = Weak; | |
break; | |
case 'C': | |
_setterType = Copy; | |
break; | |
case 'G': | |
_getter = NSSelectorFromString(attribDetail); | |
break; | |
case 'S': | |
_setter = NSSelectorFromString(attribDetail); | |
break; | |
case 'V': | |
_ivarName = attribDetail; | |
break; | |
default: | |
NSAssert(NO, @"Unknown attribute: %@", attrib); | |
} | |
} | |
if (_getter == NULL) { | |
_getter = NSSelectorFromString(_name); | |
} | |
if (_setter == NULL && _isReadOnly == NO) { | |
NSString *name = [NSString stringWithFormat:@"set%@%@:", | |
[_name substringToIndex:1].uppercaseString, | |
[_name substringFromIndex:1]]; | |
_setter = NSSelectorFromString(name); | |
} | |
} | |
return self; | |
} | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@interface NSObject (Introspection) | |
@property (class, readonly) NSArray<ClassProperty *> *classProperties; | |
@end | |
@implementation NSObject (Introspection) | |
+ (NSArray<ClassProperty *> *)classProperties { | |
NSMutableArray *clsProps = [NSMutableArray array]; | |
uint propCount; | |
objc_property_t *props = class_copyPropertyList(self.class, &propCount); | |
for (uint n = 0; n < propCount; n++) { | |
[clsProps addObject:[[ClassProperty alloc] initWithProperty:props[n]]]; | |
} | |
free(props); | |
return clsProps; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment