存在一个存储(名为visits)的数组,用于存储Visit的实例。
场景:用户点击按钮,输入一个号码,该号码作为访问成员在新创建的访问中存储为属性。
这是我的代码:
[visits addObject: [visits lastObject]];
Visit * lastVisit = [visits lastObject];
lastVisit.examDate = [NSLocale currentLocale];
lastVisit.edss_numeric = 5.5;
在检查时,我预计会在我的访问数组的末尾添加一个新的访问(它确实如此),但最后的原始访问随后更新了我想要为真正的上次访问设置的信息。简而言之,最后两次访问现在是相同的,并且最初复制的访问发生了变化(当它不应该更改时)。
目标C的基本原理我不理解,如何解决这个问题以达到我想要的效果呢?
答案 0 :(得分:4)
[visits lastObject]
返回指向类型为Visit
的对象的引用。你正在做的是,再次添加对该数组的引用。因此,如果你通过中的一个更新对象,第二个引用会受到影响,因为它们都指向同一个对象。
Visit
类是否实现NSCopying
协议?如果是,您可以创建最后一个对象的副本并将其添加到数组中,这样您就会有两个引用指向两个不同的对象:
@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
然后,您可以将最后一个对象的副本添加到数组中,如下所示:
Visit *lastVisit = [visits.lastObject copy];
lastVisit.examDate = [NSLocale currentLocale];
lastVisit.edss_numeric = 5.5;
[visits addObject:lastVisit];
答案 1 :(得分:1)
当你这样做时
[visits addObject: [visits lastObject]];
您再次向Visit
的{{1}}对象添加引用。由于它只是一个参考,而不是一个新的对象,对“new last”的任何修改都将反映在“old last”中:它是同一个对象。
要解决此问题,请插入NSArray
的副本:
last
将[visits addObject: [[Visit alloc] initWithOriginal:[visits lastObject]];
初始化程序添加到initWithOriginal:
类,并根据需要将数据复制到新对象中。