获取属性名称作为字符串

ary*_*axt 25 introspection objective-c objective-c-runtime declared-property

我需要一种方法来传递属性并获取分配给它的名称.有什么建议?

@property (nonatomic, retain) MyObject *crazyObject;

NSString *str = SOME_WAY_TO_GET_PROPERTY_NAME(crazyObject);
// Above method should return @"crazyObject"
Run Code Online (Sandbox Code Playgroud)

Osc*_*mez 23

你可以试试这个:

unsigned int propertyCount = 0;
objc_property_t * properties = class_copyPropertyList([self class], &propertyCount);

NSMutableArray * propertyNames = [NSMutableArray array];
for (unsigned int i = 0; i < propertyCount; ++i) {
  objc_property_t property = properties[i];
  const char * name = property_getName(property);
  [propertyNames addObject:[NSString stringWithUTF8String:name]];
}
free(properties);
NSLog(@"Names: %@", propertyNames);
Run Code Online (Sandbox Code Playgroud)

  • 那将打印所有属性名称.一个班级没有反思的方式来说"我将这个值归还给哪个属性?" 除了查询所有属性和比较值. (2认同)

Arv*_*vin 20

就像这一样简单......扩展Chuck已经提到的内容:

#ifndef STR_PROP
    #define STR_PROP( prop ) NSStringFromSelector(@selector(prop))
#endif
Run Code Online (Sandbox Code Playgroud)

然后你就像这样使用它:

NSString *strProp = STR_PROP(myProperty);
Run Code Online (Sandbox Code Playgroud)


clo*_*ach 14

背景

请记住,属性只是引用Apple,"用于声明类的访问器方法的语法简写." 实际上,@ property的声明本身并不起作用.您的@synthesize声明将其@property转换为两种方法:

- (void)setCrazyObject:(MyObject *)something;
- (MyObject *)crazyObject;
Run Code Online (Sandbox Code Playgroud)

使用哪一个取决于你的self.crazyObject周围的上下文.(@synthesize如果你自己没有这样做,也会创建一个匹配的实例变量.)所有这一切的分支是你无法用一个方法真正转换为属性.

提出的解决方案

您可以使用Apple已提供的内容:

NSString *foo = NSStringFromSelector(@selector(myClassProperty));
Run Code Online (Sandbox Code Playgroud)

或做一些自定义的事:

鉴于self.crazyObject实际上转换为代码运行时[self crazyObject]或者[self setCrazyObject:foo]代码运行时,您可能需要两种方法,例如:

- (NSString *)setterStringForProperty:(SEL)prop;
- (NSString *)getterStringForProperty:(SEL)prop;
Run Code Online (Sandbox Code Playgroud)

然后,您可能需要至少2个伴随方法,例如:

- (SEL)setterForPropertyName:(NSString *)propString;
- (SEL)getterForPropertyName:(NSString *)propString;
Run Code Online (Sandbox Code Playgroud)

在这些方法中,您可以使用Foundation函数 NSStringFromSelectorNSSelectorFromString在SEL和NSString之间来回转换.使用您喜欢的任何字符串操作在您的setter字符串(setCrazyObject)和您的属性名称(crazyObject)之间来回转换.

在不知道具体用例的情况下很难提供完整的解决方案,但希望这为任何试图完成类似工作的人提供了更多线索.通过将这种方法与奥斯卡的答案相结合,甚至可能会有一些有用的东西成为可能.

  • @clozach - Apple确实这样做了.`NSString*foo = NSSelectorFromString(@ selector(myClassProperty));` (5认同)
  • 你的代码中有一个错误:``NSString*foo = NSSelectorFromString(@ selector(myClassProperty));``应该是``NSString*foo = NSStringFromSelector(@selector(myClassProperty));`` (2认同)