Reputation: 14408
1) Disabled ARC.
2) I have the following code:
- (IBAction)btnsecondClicked:(id)sender {
NSString *myname;
myname = retrieveName();
}
NSString * retrieveName()
{
NSString *tmpStr = [[NSString alloc] initWithString "StackOverFlow"];
return tmpStr;
}
I tried with Analyser, and it says
"Object Leaked: allocated object is not referenced later in this execution path and has a retain count of +1"
point at line next to line where retrieName
was invoked.
My question:
What is the retain count of the the object ? Should not it be to 2 ?
because:
the first reference count is in retrieveName()
2.the second count is in btnsecondClicked()
, where myname
variable holds ?
ie: myname = retrievedName ()
-> Does not it increase the reference count ?
Upvotes: 2
Views: 88
Reputation: 4919
- (IBAction)btnsecondClicked:(id)sender {
NSString *myname; // nil object, no retain count
myname = retrieveName(); // we received the object with retain count 1 (not 2 because you are not sending `retain` to the received object)
} // you exited the function without having global reference on the object, mynames is lost because it was created inside the function, i.e. you leaked at this step
NSString * retrieveName()
{
NSString *tmpStr = [[NSString alloc] initWithString "StackOverFlow"]; // retain count is 1
return tmpStr; // tmpStr returned with retain count of 1
}
Now here is the code fixed
- (IBAction)btnsecondClicked:(id)sender {
NSString *myname;
myname = retrieveName(); // retain count = 1 and the object is the autorelease pool
}// you exited the function, autorelease pool automatically drained, the object is released, no leak
NSString * retrieveName()
{
NSString *tmpStr = [[NSString alloc] initWithString "StackOverFlow"];
return [tmpStr autorelease]; // the object with retain count=1, and added to releasePool
}
Upvotes: 1
Reputation: 352
No, because passing an object around does not add nothing to the retain count.
However, if you did
- (IBAction)btnsecondClicked:(id)sender {
NSString *myname;
myname = [retrieveName() retain];
}
Then the retain count would increase to 2, because you are explicitly declaring ownership on that particular object.
Upvotes: 1
Reputation: 100612
Think in terms of ownership — focus on the semantics of what you want to say, not the way the implementation has been written. This is object-oriented programming.
Whomever calls alloc
gets an owning reference. Anybody that calls retain
establishes ownership. So every call to either alloc or retain must be matched by a release — either an immediate release
or an autorelease
if you want it taken care of autonomously.
The norm for results on the stack is to autorelease. That's even enshrined in the rule that factory methods (e.g. [NSString +string]
return such a non-owning reference.
Upvotes: 1
Reputation: 17585
In this step, you've created string NSString *tmpStr = [[NSString alloc] initWithString "StackOverFlow"];
. So you've +1 reference count, because always alloc:
returns object with +1 count. Then where will you release this? That's why It shows as leak.
Upvotes: 2