Loosing scope of pointer type properties
This problem is creeping up in many places in my code,but the general behavior is this:
There is a view controller and a detailview controller.I create an object of a custom class in the view controller.This object contains pointer type attributes like strings.I use this to initiali开发者_Go百科ze a property of the custom class type in the detail view using a setter method. But when i try to access these properties in the detail view,i find that the pointer type attributes of the object are either shown as 'out of scope' or their type has changed to some arbitrary type.For example when i debugged last time , my nsstring properties had become CFSet or something like that. can any onne suggest the root cause for this problem?If they are changing type you're probably not retaining them.
For a string, your property should look like (in the .h file)
@property (nonatomic, copy) NSString *mString;
and you set it like
self.mString = [NSString stringWithFormat:@"hello %@", name];
which uses the property to retain (or in this case copy) the string.
However, if you do
mString = [NSString stringWithFormat:@"hello %@", name];
you have set the variable without using the property so the string is not retained - it will be autoreleased at some point in the future and you will have a pointer that's not pointing to a string anymore :)
Why use copy instead of retain for NSStrings?
Actually it's copy for anything that is immutable but has a mutable subclass (like NSDictionary, NSArray, NSSet etc).
Think of it as self defence.
What happens if you have a property like this :
@property (nonatomic, retain) NSArray *things;
and in your code you use the number of things in a loop i.e.
uint max = [things count];
for (uint n = 0; n < max; ++n) { ... }
OK, that should be fine. Until someone passes in an NSMutableArray instead of an NSArray. Your code assumes that because you have an NSArray, the count of things inside it will not change.
If someone removed an item from your NSArray (because it's really an NSMutableArray but you don't know that) while you were in that loop your code will die horribly (an out of bounds exception).
What copy does is instead of calling retain, it calls copy - making 100% sure that inside your object you have an unmutable array instead of the mutable object someone else passed in. The mutable array can be changed as much as they want - you have your own copy so you code is safer.
However, this comes at the cost of memory use - there are now two arrays in memory. It's usually worth taking the memory hit over a possible crash imho :)
NB Actually, if someone did just pass in a normal NSArray, because it's immutable the implementation of [NSArray copy]
is just a retain so 99/100 times you lose nothing by specifying copy for your property :) - this is also true for all the immutable NSxxx classes.
精彩评论