Reputation:
An array exists (named visits) which stores instances of Visit.
Scenario: A user click a button, enters a number, and that number is stored as a property on a newly created visit as a member of visits.
This is my code:
[visits addObject: [visits lastObject]];
Visit * lastVisit = [visits lastObject];
lastVisit.examDate = [NSLocale currentLocale];
lastVisit.edss_numeric = 5.5;
On inspection, I expected to have added a new visit to the end of my visits array (which it did) but the original last visit was then updated with the information I wanted to be set for the true last visit. In short, the last two visits are now identical and the originally copied visit changed (when it should not have).
What fundamentals of objective C am I not understanding and how can I fix this to achieve my desired results?
Upvotes: 1
Views: 65
Reputation: 52173
[visits lastObject]
returns a reference pointing to an object whose type is Visit
. What you are doing is, adding that reference to the array again. Because of that, if you update the object through one of them, second reference will get affected since they both point to same object.
Does the Visit
class implement NSCopying
protocol? If it does, you can create a copy of the last object and add it to the array so you'll have two references pointing to two different objects:
@interface Visit: NSObject <NSCopying>
@property (nonatomic, strong) NSLocale *examDate;
@property (nonatomic, assign) CGFloat edss_numeric;
@end
--
@implementation Visit
- (id)copyWithZone:(NSZone *)zone {
Visit *copy = [[self class] allocWithZone:zone];
if (copy) {
copy.examDate = [self.examDate copyWithZone:zone];
copy.edss_numeric = self.edss_numeric;
}
return copy;
}
@end
Then, you can add the copy of the last object to the array as follows:
Visit *lastVisit = [visits.lastObject copy];
lastVisit.examDate = [NSLocale currentLocale];
lastVisit.edss_numeric = 5.5;
[visits addObject:lastVisit];
Upvotes: 3
Reputation: 726799
When you do this
[visits addObject: [visits lastObject]];
you add a reference to the last Visit
object to your NSArray
again. Since it's only a reference, not a new object, any modifications to the "new last" will be reflected in the "old last" as well: it is the same object.
To fix this problem, insert a copy of last
instead:
[visits addObject: [[Visit alloc] initWithOriginal:[visits lastObject]];
Add initWithOriginal:
initializer to your Visit
class, and copy the data as necessary into a new object.
Upvotes: 0