Copying
There is one more change we need to make to our properties – specifically, the two properties that point to instances of NSString.
In general, when you have a property that points to an instance of a class that has a mutable subclass (like NSString or NSArray), it is safer to make a copy of the object to point to rather than pointing to an existing object that could have other owners.
For instance, imagine if a BNRItem was initialized so that its itemName pointed to an instance of NSMutableString.
NSMutableString *mutableString = [[NSMutableString alloc] init]; BNRItem *item = [[BNRItem alloc] initWithItemName:mutableString valueInDollars:5 serialNumber:@"4F2W7"]];
This code is valid because an NSMutableString is also an instance of its superclass, NSString. The problem is that the string pointed to by mutableString can be changed without the knowledge of the BNRItem that also points to it.
You may be wondering why this is a real problem. In your application, you’re not going to change this string unless you mean to. However, when you write classes for others to use, you can’t be sure how they will use your classes, and you have to program defensively.
In this case, the defense is to declare this property using the memory management attribute copy instead of strong. In BNRItem.h, change the itemName and serialNumber properties to copy.
@property (nonatomic, copy) NSString *itemName; @property (nonatomic, copy) NSString *serialNumber;
Now the generated setter method for the synthesized itemName property looks like this:
- (void)setItemName:(NSString *)str { itemName = [str copy]; }
Instead of setting itemName to point to the NSString object pointed to by str, this setter sends the message copy to that NSString. The copy method returns a new NSString object (not an NSMutableString) that has the same values as the original string, and itemName is set to point at the new string. In terms of ownership, copy gives you a strong reference to the object pointed to. The original string is not modified in any way: it doesn’t gain or lose an owner, and none of its data changes.