Graphics Programs Reference
In-Depth Information
Copying
There is one more change we need to make to our properties - specifically, the two proper-
ties 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 in-
stance 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