-2

Please solve this.

NSString *S1 = @"abc";
//retain count of s1 ??

NSString *S2 = [S1 copy];
//retain count of s2 and s1 ??

NSString *S3 = [S2 copy];
//retain count of s3 and s2 ??

NSString *S4 = [S3 retain];
//retain count of s4 and s3 ??

NSString *S1 = @"xyz";
//retain count of s1, s2, s3 and s4 ??

Do not suggest retainCount because i believe that does not give exact result.

Vaibhav Saran
  • 12,848
  • 3
  • 65
  • 75
  • This smells like homework. What do you think the answers are? – Alex Wayne Jan 17 '13 at 06:48
  • 3
    `retainCount` returns a perfectly exact result. It just may not be what you expect. – Kurt Revis Jan 17 '13 at 06:51
  • `NSLog(@"\nretain count=%d",[obj retainCount]);` returns all the way `-1`..!! – Vaibhav Saran Jan 17 '13 at 06:57
  • `retainCount` returns an unsigned value, an `NSUInteger`. You should use `%u` in your format string. – Kurt Revis Jan 17 '13 at 06:59
  • I tried that also. That returns `4294967295` everywhere. – Vaibhav Saran Jan 17 '13 at 07:02
  • 1
    Exactly. Retain Count is unreliable, unpredictable, and above all ***completely worthless***. Do not ship it in production code. – CodaFi Jan 17 '13 at 07:03
  • 3
    [Your objects are constant strings and will never get deallocated.](http://stackoverflow.com/questions/1390334/nsstring-retain-count) It doesn't matter how many times you call `copy` or `retain`, it won't affect the memory management of the object at all. – Kurt Revis Jan 17 '13 at 07:05

2 Answers2

9

Do not suggest retainCount because i believe that does not give exact result.

Correct. retainCount is useless. www.whentouseretaincount.com

You can only usefully reason about retain counts as deltas.


To answer your question, for that code, the retain count is a constant and none of the lines of code actually do much of anything. At the end of that code, S2, S3 and S4 will all have the same value; will all point to the same string (and, obviously, S1 will point to a different string).

This is because of an implementation detail. You are working with a constant string. It is, effectively, a singleton. Thus, there is never a need to copy the string (copy just does return self;) and the retain/release/autorelease methods do absolutely nothing.

bbum
  • 162,346
  • 23
  • 271
  • 359
2

Edited thanks to clarification from @KurtRevis

Assuming ARC is off, of course, you could test this yourself. But you may not understand why you are getting these results. Here is what you should be getting and why.

NSString *S1 = @"abc";
//retain count of s1 ??

S1 is a constant string literal that will never go leave memory as long as your app is running. So retain count is sort of irrelevant.

NSString *S2 = [S1 copy];
//retain count of s2 and s1 ??

S1 is unchanged. S2 is a copy of S1 with retain count of 1, with no autorelease.

NSString *S3 = [S2 copy];
//retain count of s3 and s2 ??

S2 is unchanged at 1 with no autorelease. S3 is a copy of S2 with retain count of 1, with no autorelease.

NSString *S4 = [S3 retain];
//retain count of s4 and s3 ??

S4 and S3 now point to the same object. And that one object now has a retain count of 2, with an autorelease. Once autorelease is triggered, it will have a retain count of 1, and will not be deallocated.

NSString *S1 = @"xyz";
//retain count of s1, s2, s3 and s4 ??

The old object S1 used to point to is unchanged, it's a persistant string in memory. And now S1 points to a new string which is treated the same way as what S1 used to point to.


Or just save yourself some headaches and use ARC :)

Alex Wayne
  • 178,991
  • 47
  • 309
  • 337
  • Thanx Alex. Its a part of an Interview and interviewer always tries to capture interviewee's `memory management` concepts by going beyond ARC. Offcource I can not put `retain` if i am using ARC. – Vaibhav Saran Jan 17 '13 at 07:10
  • There is no autoreleasing happening here. Referring to a constant string doesn't autorelease anything. There would be no point -- it's a constant string, it will never go away, and there is nothing to "clean up". Try setting a breakpoint on `-[NSObject autorelease]` and run the code -- the breakpoint will not be hit. – Kurt Revis Jan 17 '13 at 07:13
  • @KurtRevis Yeah I suppose. For me it's been easiest to treat them like an autoreleased instance, since you handle the object in the same fashion. But I think you are right that that's not quite correct. – Alex Wayne Jan 17 '13 at 07:15
  • @AlexWayne : All these most of us know, but kindly let us know when we print the `retainCount` why it doesn't reflect the same? – Anoop Vaidya Jan 17 '13 at 07:32
  • `retainCount` might be working in previous iOS versions because I found this post of 2009: http://stackoverflow.com/questions/1407517/can-you-send-retain-counts-to-nslog-to-aid-learning and this post of 2008: http://www.roseindia.net/iphone/objectivec/memory-management.shtml – Vaibhav Saran Jan 17 '13 at 07:37
  • 3
    The absolute retain count is useless. It won't be 1, either, because of an implementation detail. Nor will any copies of the string be made. If an interviewer asked this same question and thought the above was correct, the interviewer doesn't know what they are talking about. – bbum Jan 17 '13 at 15:26