0

I am storing some data (some floats, some strings) to a plist and then reading them back. When I read them back, I assign them to some ivars in my view controller. They are just ivars, not properties.

The floats take their values fine and I can NSLog them and see that they are correct. But no matter what I try, I can't get my NSString ivars to take the string values.

Example: array positions 6 and 7 have the strings Portland, OR" and "Pacific Daylight Time" stored in them - read back from the plist into *array.

This:

cityName = [NSString stringWithFormat:@"", [array objectAtIndex:6]];
timeZoneName = [NSString stringWithFormat:@"", [array objectAtIndex:7]];
NSLog(@" >cityName from array = %@, and now the iVar is = %@", [array objectAtIndex:6], cityName);
NSLog(@" >timeZoneName from array = %@, and now the iVar is = %@", [array objectAtIndex:7], timeZoneName);

Results in this:

>cityName from array = Portland, OR, and now the iVar is = 
>timeZoneName from array = Pacific Daylight Time, and now the iVar is = 

I put a breakpoint at the end of the method where this happens and for both NSString ivars, the little pop up message says, Invalid Summary.

Steve
  • 6,332
  • 11
  • 41
  • 53

3 Answers3

4
cityName = [NSString stringWithFormat:@"%@", [array objectAtIndex:6]];

The mistake is that you've missed the format specifier. Specifically though, if the objects in the array are already strings, you can just assign them straight to the ivar:

cityName = [array objectAtIndex:6];

Be careful about object ownership though. You don't own the object returned by objectAtIndex: so if you need to use this ivar in many different methods, obtain ownership by sending retain, and relinquish ownership using release. Alternatively if you choose to establish cityName as a retaining or copying property of your class, use the dot-notation or accessor method:

self.cityName = [array objectAtIndex:6];

// or

[self setCityName:[array objectAtIndex:6]];
dreamlax
  • 93,976
  • 29
  • 161
  • 209
  • That's embarrassing! I need some sleep. It's not a property, just a declared ivar in the header. I'll be using this for the life of the view controller (the life of the app, really) so I'll set it to the object in the array directly and retain it like `cityName = [[array objectAtIndex:6] retain];` And I'll just need to release it in `dealloc,` right? – Steve Mar 30 '11 at 04:32
  • @Steve: just an afterthought, you'll just need to be extra careful when you manually handle memory management of ivars without using setters/getters/properties. If you assign an object to the `cityName` ivar more than once without first releasing the previous value, you will end up leaking a bit of memory. – dreamlax Mar 30 '11 at 04:37
  • Are you saying that if I make it a property, I can change its value multiple times and just release it in dealloc? – Steve Mar 30 '11 at 13:58
  • @Steve: Yep, but only if you assign to the property using either of the methods in my answer. – dreamlax Mar 30 '11 at 18:51
2

If the array contains NSString instances there is no need to call +stringWithFormat:. It is a waste of CPU cycles and undoes any potential optimizations related to immutable strings. Furthermore, relying upon the results of description is never the right answer (though it is nigh unavoidable with NSStrings -- this is the one spot where you can rely on the result).

This (fixed):

cityName = [NSString stringWithFormat:@"%@", [array objectAtIndex:6]];
timeZoneName = [NSString stringWithFormat:@"%@", [array objectAtIndex:7]];

Could be:

cityName = [array objectAtIndex:6];
timeZoneName = [array objectAtIndex:7];

Copy it if you need to. As @dreamlax said, make sure you follow the memory management rules.

bbum
  • 162,346
  • 23
  • 271
  • 359
  • Could you elaborate on what you mean by `relying upon the results of description...?` And why it's never acceptable in production code? (or point me to a link?) – Steve Mar 30 '11 at 14:02
  • `description` returns "A string that describes the contents of the receiver.". It is primarily for use by the debugger and a logging convenience. It does not consider localization nor is it guaranteed to be stable over time. The string returned will often have relative garbage (outside of debugging) like the object's address. – bbum Mar 30 '11 at 19:11
0

Use below

cityName = [NSString stringWithFormat:@"%@", [array objectAtIndex:6]];

You require to use %d or %i for integers and %@ is used for string objects.

Jhaliya - Praveen Sharma
  • 31,697
  • 9
  • 72
  • 76
  • `%@` is used for any class that implements the `description` method (which is implemented in NSObject). It also works for Core Foundation types, the text that is placed is obtained from the `CFCopyDescription` method. – dreamlax Mar 30 '11 at 04:31
  • The line of code correct, the answer is not. Nor is the suggestion that `description` is ever acceptable in production code; it is not. Never ever rely on `description`. – bbum Mar 30 '11 at 04:32