views:

593

answers:

5
> .h file:
NSString *myString;
@property (nonatomic, retain) NSString *myString;

> .m file:
self.myString = [[NSString alloc] init];

If i'm not wrong i will end up with an NSString instance with retain count of +2. Right?

I'm curious because Apple's example for Location uses "self." for initialization. Why? I checked and it does show retain count to be +2.

+3  A: 

Mustafa: Yes, you're correct. (The property should be declared as copy, not retain, but that's another matter.)

Peter Hosey
+7  A: 

To answer your first question:

Yes, the retain count would be two.


To answer your second question:

The reason for using:

self.myString = x;

which is equivalent to:

[self setMyString:x];

is so that all of the property handling code is properly executed. This includes KVO notifications, and the code that automatically retains x as it is passed in.

If you were to simply set:

myString = x;

in the .m file, you would bypass all of that hidden property setting code, and simply set the myString member variable to a pointer to x.

e.James
A: 

Sorry for being indirect, i actually want to know why LocateMe application (refer to Apple's sample code) is initializing the location manager like this. If i try to correct it, the delegate methods DON'T get called. Here's the modifications i try to make:

Actual Code:

- (id) init {
self = [super init];
if (self != nil) {
 self.locationManager = [[[CLLocationManager alloc] init] autorelease];
 self.locationManager.delegate = self; // Tells the location manager to send updates to this object
}
return self;
}

Modification 1:

- (id) init {
self = [super init];
if (self != nil) {
 locationManager = [[[CLLocationManager alloc] init] autorelease];
 self.locationManager.delegate = self; // Tells the location manager to send updates to this object
}
return self;

}

Modification 2:

- (id) init {
self = [super init];
if (self != nil) {
        CLLocationManager *myLM = [[CLLocationManager alloc] init];
        self.locationManager = myLM;
        self.locationManager.delegate = self; // Tells the location manager to send updates to this object
        [myLM release];
}
return self;
}
Mustafa
you should edit your actual question to add this information instead of posting it as an answer.
Ashley Clark
+1  A: 

In your Modification 1, you're setting your instance variable directly to an autoreleased object. This means that at the end of the event loop your locationManager will be released and in this case, you'll then have a reference to a now unused block of memory.

Your Modification 2 looks correct to me, as does the sample code you've started from.

Ashley Clark
A: 

Since locationManager is an object declared in my class interface, i don't think autorelease will have an affect on it soon after the method is completly done, or am i wrong? Plus, "Modification 2" is logically correct for all other objects but if i use this implementation the Location Manager's delagete methods are not properly captured. Thanks.

Mustafa
The autorelease pool is external to your objects. Any object that is placed on it will have a release message sent to it at some undeterminable point in the future. It is very likely that it would be released immediately after your method finishes.
Ashley Clark
I'm not an expert, but since the object is an autoreleased object, i believe it will be released when the pool is released. iPhone does not support garbage collection, and NSAutoreleasePool does not release objects in the similar fashion (like garbage collector). Correct me if i'm wrong.
Mustafa
You are correct that iPhone doesn't support garbage collection and that an NSAutoreleasePool doesn't release in the same fashion as GC would. But you can't reliably know when an NSAutoreleasePool *will* be drained. At a minimum it happens at the end of the event loop, but it can happen sooner too.
Ashley Clark