我正在尝试使用property_getAttributes()运行时函数获取对象的属性属性。某些属性设置为只读。但当我试图区分retain/strong、weak和assign属性时,问题就来了。例如:
假设我们有:
@interface MyObject : NSObject
@property (assign, readonly) NSObject *prop1;
@property (strong, readonly) NSObject *prop2;
@property (weak, readonly) NSObject *prop3;
@end
我们获取属性列表并打印
int outCount;
objc_property_t *properties = class_copyPropertyList([MyObject class], &outCount);
for(i = 0; i < outCount; i++) {
objc_property_t property = properties[i];
const char *c_attributes = property_getAttributes(property);
printf("%s", c_attributes);
}
free(properties);
结果是:
T@"NSObject",R,V_prop1
T@"NSObject",R,V_prop2
T@"NSObject",R,V_prop3
因此,当属性为只读时,没有针对弱、强/保留、分配属性的特定代码:(
问题是:是否有其他方法可以知道该属性是弱、强/保留、赋值?
我还没有尝试过你的代码,但根据
https://developer.apple.com/library/mac/documentation/cocoa/conceptual/objcruntimeguide/articles/ocrtpropertyintrospection.html
R属性为只读(只读)
C该属性是上次分配的值的副本(副本)。
&该特性是对上次指定(保留)的值的引用。
N这个性质是非原子的。
G该属性定义了一个自定义的getter选择器名称。名称跟在G后面(例如,GcustomGetter,)。
S该属性定义了一个自定义的setter选择器名称。名称跟在S后面(例如,ScustomSetter:,)。
D属性是动态的(@dynamic)。
W该属性是弱引用(__weak)。
p该属性符合垃圾收集的条件。
t使用旧样式编码指定类型。
要快速回答您的问题,答案是否定的。
这里的问题是属性(ARC中的assign
、unsafe_unretained
、strong
、weak
、copy
和MRC中的assign
、retain
、copy
)的内存管理语义仅在自动生成的setter代码中具有任何应用。如果您为属性编写自己的setter,我们当然鼓励您自己实现语义(但不是必需的)。这些属性的getter根本不会被这些属性属性修改。考虑这个代码:
@interface FooBar ()
@property (nonatomic, strong, readonly) NSString* foobar;
@end
@implementation FooBar
- (NSString*) foobar {
return [NSString stringWithFormat:@"aString"];
}
在这些情况下,调用者将进行强引用或弱引用,并且返回值必须至少与调用代码完成语句所需的时间一样长。在弱引用的情况下,它将在之后转到nil
,因为具有strong
的属性不能保证为您保留引用的对象。最终,对readonly
属性的内存管理只不过是一种安慰剂,最终主要通过习惯或风格来实现。@property (nonatomic, readonly) ...
是完全合法的,但当我们习惯于在属性声明中遇到内存属性时,会感到困惑。
PS:运行时中还有另一个名为property_copyAttributeList
的函数,我发现它更容易解析这些信息(它使用结构为您分解组件)。