Reputation: 6758
The common practice in IOS setters is the following:
- (void)setMyString:(NSString *)newString {
if ( newString != myString ) {
[myString release];
myString = [newString retain];
}
}
On the contrary this is not good practice
- (void)setMyString:(NSString *)newString {
if ( myString != nil ) [myString release];
myString = [newString retain];
}
}
What is the reason checking for equality in the first case? What is the problem in the seconds case?
Upvotes: 0
Views: 262
Reputation: 11841
I know this is somewhat redundant, but...
If the new and old object are the same then you send release
to the old object and it gets deallocated, the pointer to the new object will become a dangling pointer as the object it pointed to will no longer exist (since it pointed to the same object as the old object pointer). Ex. if myString
and newString
point to the same instance who has a retain count of one, then you subtract one, it'll equal zero. it's too late to add one now, because it'll get deallocated. However, reverse the calls to retain
and release
and it should be fine. If the retain count is one and you add one, it's now two, and you can safely send release. In general, I'd say before you disown an object, assert ownership of the new one first.
Also, the first type of setter would be what you would use for retain
/strong
style setter. If it were assign
you wouldn't need to retain/release as no ownership is supposed to be asserted. NSStrings often have a copy
style setter which copies the argument and uses that, which would create a copy instead of retaining. I would generally use copy
for anything with a mutable subclass as you wouldn't want someone passing in a NSMutableString and mutating it behind your back. This page goes into accessors, and you'll notice that they retain the new value before releasing the old one, and explain why.
Upvotes: 0
Reputation: 71
You may take this to though the memory management, https://developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/.
Upvotes: 0
Reputation: 3545
If you set something like this [object setMyString:[object myString]];
without checking for equality - it will be crash! Because it will be released before you send it message retain. (in case when only object own string). Also in first example we checking for equality to avoid extra operations.
Upvotes: 2