当设置为只读时,property_getAttributes()不会区分保留属性、强属性、弱属性和赋值属性



我正在尝试使用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中的assignunsafe_unretainedstrongweakcopy和MRC中的assignretaincopy)的内存管理语义仅在自动生成的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的函数,我发现它更容易解析这些信息(它使用结构为您分解组件)。

最新更新