Whoami
Whoami

Reputation: 14408

What is the reference count of an object in the following program?

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:

  1. 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

Answers (4)

Basheer_CAD
Basheer_CAD

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

galrito
galrito

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

Tommy
Tommy

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

Mani
Mani

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

Related Questions