Graphics Programs Reference
In-Depth Information
This protocol only has one method -
copyWithZone:
. When an object is sent
copy
, it
really calls
copyWithZone:
and returns a new instance with the same values as the
copied instance. (
copyWithZone:
is a relic like
allocWithZone:
. Zones don't mat-
ter anymore - you implement the
withZone:
methods in your classes, but send mes-
sages without the
withZone:
part.)
In
RSSChannel.m
, implement
copyWithZone:
to return a new instance of
RSSChannel
.
- (id)copyWithZone:(NSZone *)zone
{
RSSChannel *c = [[[self class] alloc] init];
[c setTitle:[self title]];
[c setInfoString:[self infoString]];
c->items = [items mutableCopy];
return c;
}
This method is almost entirely straightforward. A new channel is created, and it is given
the same
title
and
infoString
as the receiver. Instead of sending
alloc
to
RSSChannel
, we send it to the class of the object being copied, just in case we subclass
RSSChannel
. (Without this, a copy of a subclass would be an instance of
RSSChan-
nel
and not the subclass.)
The curious bit about this method is how the
items
array is set. We know that an object's
instance variables can be accessed directly within one of its methods. To access another
object's instance variable, though, you must use an accessor method. However, there is no
setter method for a channel's
items
instance variable, so the channel being copied can't
change the
items
array of its copy. But wait! An Objective-C object is a C structure.
When you have a pointer to a structure, you can access its members using the arrow (
->
).
There are two caveats about accessing an instance variable directly. First, the setter meth-
od doesn't get called.This causes a problem if the setter method performs some additional
operations on the incoming value. So, if there is a setter method, you should use that in-
stead.
Second, you can't access an instance variable directly whenever you please. The only
reason it works here is because you are within the implementation for
RSSChannel
, and
the object whose instance variables you are directly accessing is an instance of
RSSChannel
, too. It wouldn't work if, say,
ListViewController
tried to access an
instance variable of the
RSSChannel
directly.