3 回答
TA贡献1860条经验 获得超8个赞
要实现NSCopying,您的对象必须响应-copyWithZone:选择器。声明符合条件的方式如下:
@interface MyObject : NSObject <NSCopying> {
然后,在对象的实现中(您的.m文件):
- (id)copyWithZone:(NSZone *)zone
{
// Copying code here.
}
您的代码应该做什么?首先,创建该对象的新实例-您可以调用[[[self class] alloc] init]以获取当前类的初始化对象,该对象对子类非常有用。然后,对于NSObject支持复制的子类的任何实例变量,可以调用[thatObject copyWithZone:zone]新对象。对于原始类型(int,char,BOOL和朋友)刚刚成立的变量是相等的。因此,对于您的目标供应商,它看起来像这样:
- (id)copyWithZone:(NSZone *)zone
{
id copy = [[[self class] alloc] init];
if (copy) {
// Copy NSObject subclasses
[copy setVendorID:[[self.vendorID copyWithZone:zone] autorelease]];
[copy setAvailableCars:[[self.availableCars copyWithZone:zone] autorelease]];
// Set primitives
[copy setAtAirport:self.atAirport];
}
return copy;
}
TA贡献1815条经验 获得超10个赞
该答案与已接受的答案相似,但是使用allocWithZone:并针对ARC更新了该答案。NSZone是分配内存的基础类。尽管NSZone在大多数情况下忽略可能有效,但这仍然是不正确的。
为了正确实现,NSCopying您必须实现一种协议方法,该方法分配具有与原始值匹配的属性的对象的新副本。
在标题的接口声明中,指定您的类实现了该NSCopying协议:
@interface Car : NSObject<NSCopying>
{
...
}
在.m实现中,添加一个-(id)copyWithZone类似于以下内容的方法:
- (id)copyWithZone:(NSZone*)zone
{
Car* carCopy = [[[self class] allocWithZone:zone] init];
if (carCopy)
{
carCopy.isAvailable = _isAvailable;
carCopy.transmissionType = _transmissionType;
... // assign all other properties.
}
return carCopy;
}
TA贡献1946条经验 获得超4个赞
只需调用object.copy()即可创建副本。
我没有使用copy()过值类型,因为它们是“自动”复制的。但是,我不得不使用copy()的class类型。
我忽略了该NSZone参数,因为文档称它已弃用:
该参数被忽略。存储区不再由Objective-C使用。
另外,请注意,这是一个简化的实现。如果您有子类,它会变得有些棘手,您应该使用动态类型:type(of: self).init(transmissionType: transmissionType)。
class Vendor {
let vendorId: String
var availableCars: [Car] = []
init(vendorId: String) {
self.vendorId = vendorId
}
}
extension Vendor: NSCopying {
func copy(with zone: NSZone? = nil) -> Any {
let copy = Vendor(vendorId: vendorId)
if let availableCarsCopy = availableCars.map({$0.copy()}) as? [Car] {
copy.availableCars = availableCarsCopy
}
return copy
}
}
class Car {
let transmissionType: String
var isAvailable: Bool = false
var fees: [Double] = []
init(transmissionType: String) {
self.transmissionType = transmissionType
}
}
extension Car: NSCopying {
func copy(with zone: NSZone? = nil) -> Any {
let copy = Car(transmissionType: transmissionType)
copy.isAvailable = isAvailable
copy.fees = fees
return copy
}
}
- 3 回答
- 0 关注
- 702 浏览
添加回答
举报