First, you need to understand the difference between instance variables and properties and getter/setters.
- instance variables (ivars) are variables stored in
your object. You access an ivar from within a method simply by naming it (eg "userName").
- properties define an
interface to your object, allowing
information to be read and/or written
to your object.
- getters/setters implement that interface and may use an ivar as backing storage
You access a property by using a getter/setter, either explicitly (eg [self userName]) or (equivalently) using dot syntax self.userName. Note that these two notations are exactly identical. You declare a property (ie, you declare an interface to your object) using @property in the interface of your object, something like:
@property (copy) NSString* userName;
This declartion is essentially equivalent to typing:
- (NSString*) userName;
- (void) setUserName: (NSString*) theUserName;
You implement a property, either by using @synthesize (which simply tells the compiler to write the getter/setter for you) or by implementing it yourself (ie, you write methods implementation for userName and setUserName). There is also a rarely used third option, @dynamic, which tells the compiler you will handle the methods at run time, essentially just silincing the warning you would otherwise get.
Next, you need to read and understand the memory management rules. Its only 9 short paragraphs, go read it now, I'll wait. Done? good.
Further, you need to know that you should not use getters/setters in either the init or dealloc routines.
So your init routine should look something like this:
- (id)initWithUserName:(NSString *)user{
userName = [user copy];
userInfo = [[TwitterHelper fetchInfoForUsername:user] retain];
displayName = [[userInfo valueForKey:@"name"] copy];
image = [[NSURL URLWithString:[userInfo valueForKey:@"profile_image_url"]] copy];
updates = [[TwitterHelper fetchTimelineForUsername:userName] retain];
return self;
}
Note that you take ownership of each value you store in an ivar with retain or copy. Generally, you use copy for NSString to convert an NSMutableStrings into NSStrings you own, rather than retain which would leave you holding a reference to a possibly mutable string. The same issue applies to NSArray/NSDictionary, but we will assume TwitterHelper intends to hand off the fetched data.
Your dealloc will have to release the various ivars:
- (void)dealloc
{
[userName release];
[displayName release];
[updates release];
[userInfo release];
[image release];
[super dealloc];
}
Anywhere else in your code you would use self.userName to access or change the properties, rather than access the ivars directly.
Note that you might consider not storing the displayName (and similarly image) at all, but simply implement a property getter that retrieves it from userInfo. To do this, delete the displayName ivar, change the property to:
@property (readonly) NSString *displayName;
remove the @synthesize displayName, and add a manual getter:
- (NSString*) displayName
{
return [userInfo valueForKey:@"name"];
}
and remove the release in dealloc.
Note that you do not need to retain/release the value in displayName - you return a value that the receiver does not own and it is up to them to copy/retain it if they want to keep it.