复制数组中的最后一个对象,然后更新目标C.

时间:2016-05-05 19:33:06

标签: objective-c arrays

存在一个存储(名为visits)的数组,用于存储Visit的实例。

场景:用户点击按钮,输入一个号码,该号码作为访问成员在新创建的访问中存储为属性。

这是我的代码:

[visits addObject: [visits lastObject]];
Visit * lastVisit = [visits lastObject];
lastVisit.examDate = [NSLocale currentLocale];
lastVisit.edss_numeric = 5.5;

在检查时,我预计会在我的访问数组的末尾添加一个新的访问(它确实如此),但最后的原始访问随后更新了我想要为真正的上次访问设置的信息。简而言之,最后两次访问现在是相同的,并且最初复制的访问发生了变化(当它不应该更改时)。

目标C的基本原理我不理解,如何解决这个问题以达到我想要的效果呢?

2 个答案:

答案 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:类,并根据需要将数据复制到新对象中。