9 Mar 2010
Objective-C Puzzle
A blog entry with a gracious nod to Gilad and Josh’s series of Java puzzlers.
Why does this code excerpt produce different results in the simulator vs running the app on the iPhone itself?
In my AllRides class which contains the information about all the club’s bike rides I have the initialization method below. In the ViewController for the preferences screen I then access and display the AllRides.club property.
AllRides.m:
- init {
if (self = [super init]) {
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
club = (NSString *)[userDefaults objectForKey:kClub];
if (club == nil) {
club = kDefaultClub;
}
}
return self;
}
Preferences.m (in – (void) viewDidLoad):
club.text = [[AllRides sharedRides] club];
When running in the simulator all appears well. The club name nicely appears:
When running the app on the iPhone the field is empty:
Changing the AllRides init method explicitly setting self.club makes both runtime environments behave the same expected way:
- init {
if (self = [super init]) {
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
self.club = (NSString *)[userDefaults objectForKey:kClub];
if (self.club == nil) {
self.club = kDefaultClub;
}
}
return self;
}
Suggestions? Answers?
I guess the underlying question is what the subtle differences are between club and self.club.



Where do you Alloc the AllRides class?
In Preferences.m the Class is accessed, not an Instance. Isn’t that strange? Singleton-ish behavior?
(that does not answer your question, not yet)
Leon Wubbe
March 10th, 2010 at 5:53 pmpermalink
It’s allocated when the main viewcontroller is instantiated. AllRides is a singleton indeed.
Onno
March 10th, 2010 at 6:10 pmpermalink
Assumption:
self.club accesses the instance variable directly
club (or [self club]) uses the accessor methods of this property
How is this property declared in AllRides.h?
assign or retain or copy?
Leon Wubbe
March 10th, 2010 at 6:37 pmpermalink
retain
admin
March 11th, 2010 at 11:16 ampermalink
retain is OK (afaik)
How can we test if my assumption is right?
add readonly to the declaration of the property and try to change the value, using both ways.
Leon Wubbe
March 12th, 2010 at 5:36 ampermalink
Found on an iPhone forum:
The following statements do exactly the same: The property ‘value’ is accessed as a property (using getter/setter)
self.value = newValue;
[self setValue:newValue];
The following statement doesn’t use getter/setter: The property ‘value’ is accessed directlty
value = newValue;
Leon Wubbe
March 14th, 2010 at 8:58 ampermalink
And that is causing the difference. It is odd though that it leads to different behavior in the simulator vs the device.
Onno
March 15th, 2010 at 4:22 pmpermalink
I read in an iPhone Blog that one should never use self.property or [self property], just property is the best.
Reason: No unwanted side effects (not specified)
That is exactly the opposite of what you have discovered…
Leon Wubbe
March 16th, 2010 at 11:29 ampermalink