tags:

views:

22

answers:

1

Hi,

The objective C docs say this about retain attribute in properties:

"retain Specifies that retain should be invoked on the object upon assignment. (The default is assign.) The previous value is sent a release message."

I thought I understood properties and attributes until I saw something like this in the UITableViewCell reference guide:

@property(nonatomic, readonly, retain) UIImageView *imageView

then reading the above really confused me.

my questions: 1) suppose I have:

@interface SomeClass: NSObject {
   NSString *b;
 }
@property (nonatomic,retain) NSString *b;
@end

then in the implementation file:

@implementation SomeClass
@synthesize b;

- (id) initWithSomeString(NSString *c) {
    if (self = [super init]) {
        b = c;
     }
}
@end

this will not increment the retain count of the object pointed to by "b" correct? I am confused now about this because objective C doc says that:

"retain Specifies that retain should be invoked on the object upon assignment. (The default is assign.) The previous value is sent a release message."

2) If the above is correct, then the retain attribute only increments retain count when the setter is called correct?

3) I have heard in some places that it isn't good to call the setter method of an object in its own initializer. Why? To me if you it isn't good to do that then one would have to do:

NSString *b = [someOtherString retain];

which seems odd considering you have made a property out of "b".

4) Having "@property (retain, readonly) SomeObject *t; like in the UITableViewCell example above is also confusing. "readonly" means no getter is synthesized. If my understanding of "retain" is correct (that is it only happens in the setter), then this seems really contradictory.

Thanks in advance!

A: 

b=c; will not increment the retain count, but

self.b=c; will increment the retain count.

2) yes, the second calls the setter, so it increments the retain count. The first is a primitive, C assignment.

3) actually, it should be:

b = [someothestring copy];

you've just declared a local, overriding access to your instance variable, assigned it a (now over-retained) object, and leaked when you leave this function.

4) retain, because internally, the object is retained. read-only, because code that uses this class isn't allowed to set that field, only the class is.

DavidPhillipOster
Thanks for your answer but as it pertains to #4, I am still a bit confused. I didn't understand what you meant by "retain, because internally, the object is retained". As I understand, you can explicitly retain the object in the initializer but because it has a read only attribute you cannot use a setter (a synthesized one) to do it. So the "retain" in the attribute seems redundant if your only method of retaining it is to explicitly call retain on it.
the 'retain' in the @property means that if you don't define a setter, the compiler will define one like: - (void)setFoo:(NSString *)newFoo { if (foo != newFoo) { [foo release]; foo = [newFoo retain]; } just because it says readonly in the .h file does not stop you from overriding the @property line in your .m file in a @interface MyClass() block.
DavidPhillipOster