property_getAttributes() 在设置为只读时在保留、强、弱和分配属性之间没有区别

Posted

技术标签:

【中文标题】property_getAttributes() 在设置为只读时在保留、强、弱和分配属性之间没有区别【英文标题】:property_getAttributes() does not make difference between retain, strong, weak and assign properties when set read-only 【发布时间】:2014-01-07 14:11:22 【问题描述】:

我正在尝试使用 property_getAttributes() 运行时函数获取对象的属性。某些属性设置为只读。但是当我尝试区分保留/强、弱和分配属性时,问题就来了。例如:

假设我们有:

@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

...所以没有针对弱、强/保留的特定代码,当属性为只读时分配属性:(

问题是:有没有其他方法可以知道属性是弱、强/保留、分配?

【问题讨论】:

我很好奇。你为什么要这样做? 【参考方案1】:

我没有试过你的代码,但是根据

https://developer.apple.com/library/mac/documentation/cocoa/conceptual/objcruntimeguide/articles/ocrtpropertyintrospection.html

R 该属性是只读的(只读)

C 该属性是上次分配的值的副本(副本)。

& 该属性是对上次分配(保留)的值的引用。

N 该属性是非原子的(nonatomic)。

G 该属性定义了一个自定义的 getter 选择器名称。名称跟在 G 后面(例如 GcustomGetter)。

S 该属性定义了一个自定义设置器选择器名称。名称跟在 S 后面(例如,ScustomSetter:,)。

D 该属性是动态的 (@dynamic)。

W 该属性是弱引用 (__weak)。

P 该属性符合垃圾回收条件。

t 使用旧式编码指定类型。

【讨论】:

【参考方案2】:

要快速回答您的问题,答案是否定的。

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

【讨论】:

以上是关于property_getAttributes() 在设置为只读时在保留、强、弱和分配属性之间没有区别的主要内容,如果未能解决你的问题,请参考以下文章