Reputation: 795
I'm learning Objective C with the book "Programming with Objective C", but I'm stuck with the exercises 3 on page 66.
I have the following properties:
@property (copy, readonly) NSString *lastName;
@property (copy, readonly) NSString *firstName;
the following methods:
+ (id) personWithLastName:(NSString *)aLastName andFirstName:(NSString *)aFirstName {
return [[self alloc] initWithLastName:aLastName andFirstName:aFirstName;
}
- (id) initWithLastName:(NSString *)aLastName andFirstName:(NSString *)aFirstName {
self = [super init];
if (self) {
_lastName = aLastName;
_firstName = aFirstName;
}
return self;
}
- (void) sayHello {
NSString *greeting = [NSString stringWithFormat:@"Hello, %@ %@!", [self firstName], [self lastName]];
[self saySomething:greeting];
}
and the following code in the main:
NSMutableString *firstName = [NSMutableString stringWithString:@"Steve"];
NSString *lastName = @"Jobs";
XYZPerson* firstPerson = [XYZPerson personWithLastName:lastName andFirstName:firstName];
[firstPerson sayHello];
which correctly print "Hello, Steve Jobs!".
Later, I added the following lines:
[firstName setString:@"John"];
[firstPerson sayHello];
which edit the property firstName in the object firstPerson, and print "Hello, John Jobs!". However, firstName have the copy attribute, so why this happen?
Upvotes: 0
Views: 90
Reputation: 35616
Well let's break this down...
This property says that we want only an accessor to be generated (the readonly
part) plus we take ownership of the object via copy
upon assignment (which in this case is never gonna happen because of the readonly
)
@property (copy, readonly) NSString *lastName;
So a better form would be (unless you're interested in redeclaration of the property as readwrite
in a class extension, like in this answer):
@property (readonly) NSString *lastName;
and now we copy inside our init
method before assignment to the backing ivars:
- (id) initWithLastName:(NSString *)aLastName andFirstName:(NSString *)aFirstName {
self = [super init];
if (self) {
_lastName = [aLastName copy];
_firstName = [aFirstName copy];
}
return self;
}
and of course the same applies to your other property also.
Upvotes: 1
Reputation: 4805
The firstName and Lastname you are using in your main method are not the properties you declared, but instead new instance variables. To access the properties you want you can use _firstName to use the ivar or self.firstName to use the property's setter and getter methods.
EDIT: Disregard the above. Because you are using the ivar directly instead of calling the accessor method, the copy is not being made -- you have to call copy yourself.
Upvotes: 0