这是解释
List of class properties in Objective-C
如何使用class_copyPropertyList在运行时获取类的所有属性。
我测试了这个并且工作正常。
我注意到它只会从该类获取属性,而不是它的子类。
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
如果我在JustForThisUT上使用它,我将获得2个属性(public_access& private_access)
如果我在JustForThisUTParent上使用它,我将获得2个属性(my_public_access& my_private_access)
但是对于JustForThisUTParent我期望从JustForThisUT获得4,从JustForThisUTParent获得2。
我的问题是
如何从当前类和所有子类获取属性?
它甚至可能吗?
答案 0 :(得分:4)
您必须先找到所有子类,然后使用class_copyPropertyList()列出每个类的属性,并根据需要进行单独处理。
然而,这有一个糟糕的代码味道。这种动态,反射沉重的编程水平与ObjC的真正设计背道而驰。您最终会得到一个难以维护的脆弱代码库。
如果你真的想要这种性质的动态,那么在每个类上实现一个类方法,它返回你想要能够动态访问的属性名列表。
答案 1 :(得分:0)
找到所有超类相当简单(我认为这是你的意思,而不是子类);你只需循环直到class.superclass == NSObject.class。
请注意@bbum关于这是一个糟糕的代码味道的评论。阅读他的答案并考虑其他方法,并真正考虑为什么要这样做,以及是否有更好的方法。
也就是说,这是一个完整的代码示例,它从类中检索所有BOOL属性。将其扩展到其他属性类型会很容易 - 请参阅链接的问题。
/**
* 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;
}