Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

kalimba

macrumors regular
Original poster
Jun 10, 2008
102
0
I'm writing a class that uses the UIDevice class to obtain information about the device on which my application is running. My class queries certain properties from the [UIDevice currentDevice] and caches the returned NSStrings in class members.

On the simulator, for certain UIDevice properties -- 'name' and 'model' -- I'm getting NSStrings returned with retain counts of 2147483647. For the other properties I'm querying -- 'uniqueIdentifier', 'systemName' and 'systemVersion' -- I'm getting NSStrings with (proper) retain count of 1.

Additionally, when I run on my device, the behavior changes slightly in that the 'name' property suddenly works correctly and returns an NSString with retain count of 1. Although the 'model' property still returns an NSString with retain count of 2147483647.

Has anyone else seen this behavior? Is this a known issue?
 

kalimba

macrumors regular
Original poster
Jun 10, 2008
102
0
The strings returned should all be autoreleased objects.

Right. Which means the 'temp' string in the snippet below should have a retain count of 1, correct?
Code:
UIDevice *	device = [UIDevice currentDevice];
	
NSString * temp = [device model];
NSLog( @"temp.retainCount is %u", temp.retainCount );
I'm definitely seeing a retain count of 2147483647 on the NSString returned using this code.
 

robbieduncan

Moderator emeritus
Jul 24, 2002
25,611
893
Harrogate
Right. Which means the 'temp' string in the snippet below should have a retain count of 1, correct?
Code:
UIDevice *	device = [UIDevice currentDevice];
	
NSString * temp = [device model];
NSLog( @"temp.retainCount is %u", temp.retainCount );
I'm definitely seeing a retain count of 2147483647 on the NSString returned using this code.

Why are you using %u? retainCount returns a NSUInteger which is an int (on a 32-bit architecture). %u is for unsigned ints, not signed ones. You should use %i.
 

kalimba

macrumors regular
Original poster
Jun 10, 2008
102
0
Why are you using %u? retainCount returns a NSUInteger which is an int (on a 32-bit architecture). %u is for unsigned ints, not signed ones. You should use %i.
I can guarantee that this is not the real problem here. Replacing my %u with a %i won't change the fact that the NSString has a retain count of 2147483647.
 

robbieduncan

Moderator emeritus
Jul 24, 2002
25,611
893
Harrogate
I can guarantee that this is not the real problem here. Replacing my %u with a %i won't change the fact that the NSString has a retain count of 2147483647.

Yes it will: by using %u you are telling NSLog to treat that binary value as unsigned. As it is a signed value you should be using %i. This is very basic Computer Science. I'd suggest reading up on Two's Complement for an explanation of how signed numbers are actually stored. Note the two's complement representation of -1. Now think of how that would be interpreted if it was unsigned. You will soon see that the retain count is not, in fact, 2147483647.
 

kalimba

macrumors regular
Original poster
Jun 10, 2008
102
0
Isn't 2147483647 = -1 when you use unsigned instead of signed?
I don't have a hex/decimal calulator handy, but this is also what I suspect. Actually, I was thinking it was 0x7FFFFFFF, and after some Googling I've found that my other suspicion -- that the crazy retain count occurs when static strings are returned -- is probably correct. I suspect the "model" getter is always returning a static string.

Apparently, this is correct behavior. :eek:
 

kalimba

macrumors regular
Original poster
Jun 10, 2008
102
0
Yes it will: by using %u you are telling NSLog to treat that binary value as unsigned. As it is a signed value you should be using %i. This is very basic Computer Science. I'd suggest reading up on Two's Complement for an explanation of how signed numbers are actually stored. Note the two's complement representation of -1. Now think of how that would be interpreted if it was unsigned. You will soon see that the retain count is not, in fact, 2147483647.
I appreciate the help, but I am aware of points you're trying to make. I understand that interpreting the same pattern of bits as a signed value is different from that as an unsigned value. My point was not that that retain count was "2147483647" vs. "-1", but that it was not the value (1) that I was expecting.

BTW, in theory, the string formatting change you suggested should have changed the display from "2147483647" to "-1" for the retain count, but even with that change, the value still shows as "2147483647". Weird.
 

robbieduncan

Moderator emeritus
Jul 24, 2002
25,611
893
Harrogate
...the crazy retain count occurs when static strings are returned -- is probably correct. I suspect the "model" getter is always returning a static string.

Apparently, this is correct behavior. :eek:

This is a compiler option I think: to turn static strings in the code (@"My String" style strings) into static objects. It can reduce memory footprint as two identical strings created this way will, in fact, be the same object. As NSStrings are immutable it's perfectly safe to do this...
 

dejo

Moderator emeritus
Sep 2, 2004
15,982
452
The Centennial State
BTW, in theory, the string formatting change you suggested should have changed the display from "2147483647" to "-1" for the retain count, but even with that change, the value still shows as "2147483647". Weird.
I don't believe statics work this way. And you shouldn't need to be worried about the retain count for a static. That's the compiler's job.
 

kalimba

macrumors regular
Original poster
Jun 10, 2008
102
0
I don't believe statics work this way. And you shouldn't need to be worried about the retain count for a static. That's the compiler's job.

I'm not sure if you're saying I shouldn't retain the returned string, or that I just shouldn't worry about the details. I'm obligated to retain whatever NSString UIDevice (or any other class API, for that matter) returns me, whether it is static or not, so that's the approach I'm taking.

Just for some background, I started peeking at the retain counts to make sure that I was retaining and releasing the NSString objects properly. I was a little confused to find a retain count of 0x7FFFFFFF, but now that I understand what it means, I realize that I'm doing things correctly.
 

dejo

Moderator emeritus
Sep 2, 2004
15,982
452
The Centennial State
I'm not sure if you're saying I shouldn't retain the returned string, or that I just shouldn't worry about the details. I'm obligated to retain whatever NSString UIDevice (or any other class API, for that matter) returns me, whether it is static or not, so that's the approach I'm taking.
Are you allocating space for the returned string? Based on your code above, I'd say no. (NSString * temp = [device model];) You're just creating a pointer to the space it already occupies. Therefore, you don't need to retain it.
 

kalimba

macrumors regular
Original poster
Jun 10, 2008
102
0
Are you allocating space for the returned string? Based on your code above, I'd say no. (NSString * temp = [device model];) You're just creating a pointer to the space it already occupies. Therefore, you don't need to retain it.

I am admittedly a newb to Objective-C/Cocoa/iPhone programming, but that goes against nearly everything I've read regarding proper memory management in this environment. Perhaps what you're saying applies to the code snippet I posted which uses the "temp" variable, but if you go back to my OP, you'll see how I'm actually using the NSString objects returned from UIDevice.
My class queries certain properties from the [UIDevice currentDevice] and caches the returned NSStrings in class members.
So what I'm doing is querying the UIDevice for the values and keeping them around in my singleton class for the duration of the application. If I don't retain the NSString objects UIDevice returns to me, I run the risk of having a dangling pointer, since those NSString objects are autoreleased.
 

dejo

Moderator emeritus
Sep 2, 2004
15,982
452
The Centennial State
I am admittedly a newb to Objective-C/Cocoa/iPhone programming, but that goes against nearly everything I've read regarding proper memory management in this environment. Perhaps what you're saying applies to the code snippet I posted which uses the "temp" variable, but if you go back to my OP, you'll see how I'm actually using the NSString objects returned from UIDevice.

So what I'm doing is querying the UIDevice for the values and keeping them around in my singleton class for the duration of the application. If I don't retain the NSString objects UIDevice returns to me, I run the risk of having a dangling pointer, since those NSString objects are autoreleased.
I would just define those variables as NSString * then. I don't think you get any benefit from "re-storing" the value of those NSStrings within your singleton. Unless you are planning on changing them...
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.