I'm trying to get the property attributes of an object with the property_getAttributes() runtime function. Some properties are set read-only. But the problem comes when I try to make the difference between retain/strong, weak and assign properties. e.g.:
Let's say we have:
@interface MyObject : NSObject
@property (assign, readonly) NSObject *prop1;
@property (strong, readonly) NSObject *prop2;
@property (weak, readonly) NSObject *prop3;
@end
We get the property list and print
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);
The result is:
T@"NSObject",R,V_prop1
T@"NSObject",R,V_prop2
T@"NSObject",R,V_prop3
...so no specific code for weak, strong/retain, assign properties when they are read-only :(
The question is: is there any other way to know if the property is weak, strong/retain, assign?
To answer your question quickly, the answer is no.
The issue here is that memory management semantics for properties (those are
assign
,unsafe_unretained
,strong
,weak
,copy
in ARC andassign
,retain
,copy
in MRC) only have any application in automatically generated setter code. Should you write your own setter for the property you are of course encouraged to implement the semantic yourself (but not required). The getter of these properties are not modified at all by these property attributes. Consider this code:In these situations the caller will make a either a strong or weak reference and the return value must live for at least as long as the calling code needs to complete the statement. In the case of a weak reference it will go to
nil
afterwards since a property withstrong
does not guarantee that the referenced object will be kept for you. Ultimately, memory management onreadonly
properties are nothing more than a placebo that end up there mostly by either habit or style@property (nonatomic, readonly) ...
is perfectly legal, but confusing when we are used to encountering a memory attribute in the property declaration.PS: There's another function in the runtime called
property_copyAttributeList
which I find much easier for parsing this information (it uses structs to break up the components for you).