实施NSCopying

我已经阅读了NSCopying文档,但对于如何实施所需的内容仍然不确定。


我的课Vendor:


@interface Vendor : NSObject 

{

    NSString        *vendorID;

    NSMutableArray  *availableCars;

    BOOL            atAirport;

}


@property (nonatomic, copy) NSString *vendorID;

@property (nonatomic, retain) NSMutableArray *availableCars;

@property (nonatomic, assign) BOOL atAirport;


- (id)initFromVehVendorAvailsDictionary:(NSDictionary *)vehVendorAvails;


@end

的Vendor类有称为对象的数组Car。


我的Car对象:


@interface Car : NSObject 

{

    BOOL            isAvailable;

    NSString        *transmissionType;

    NSMutableArray  *vehicleCharges; 

    NSMutableArray  *fees; 

}


@property (nonatomic, assign) BOOL isAvailable;

@property (nonatomic, copy) NSString *transmissionType;

@property (nonatomic, retain) NSMutableArray *vehicleCharges;

@property (nonatomic, retain) NSMutableArray *fees;


- (id) initFromVehicleDictionary:(NSDictionary *)vehicleDictionary;


@end

因此,Vendor拥有一个Car对象数组。Car拥有2个其他自定义对象的数组。


双方Vendor并Car从字典初始化。我将添加其中一种方法,它们可能相关,也可能不相关。


-(id)initFromVehVendorAvailsDictionary:(NSDictionary *)vehVendorAvails {


    self.vendorCode      = [[vehVendorAvails objectForKey:@"Vendor"] 

                           objectForKey:@"@Code"];


    self.vendorName      = [[vehVendorAvails objectForKey:@"Vendor"] 

                           objectForKey:@"@CompanyShortName"];


    self.vendorDivision  = [[vehVendorAvails objectForKey:@"Vendor"]   

                           objectForKey:@"@Division"];


    self.locationCode    = [[[vehVendorAvails objectForKey:@"Info"] 

                           objectForKey:@"LocationDetails"] 

                           objectForKey:@"@Code"];


    self.atAirport       = [[[[vehVendorAvails objectForKey:@"Info"] 

                           objectForKey:@"LocationDetails"] 

                           objectForKey:@"@AtAirport"] boolValue];

 

因此,总结一下这个可怕的问题。


我需要复制Vendor对象数组。我相信我需要在上实现NSCopying协议Vendor,这可能意味着我也需要在协议上实现,Car因为它Vendor包含Cars 数组。这意味着我还需要在属于该Car对象的2个数组中持有的类上实现它。


如果我能在上实现NSCopying协议方面获得一些指导,我真的很感激Vendor,我在任何地方都找不到关于此的任何教程。


胡子哥哥
浏览 699回答 3
3回答

桃花长相依

要实现NSCopying,您的对象必须响应-copyWithZone:选择器。声明符合条件的方式如下:@interface MyObject : NSObject <NSCopying> {然后,在对象的实现中(您的.m文件):- (id)copyWithZone:(NSZone *)zone{&nbsp; &nbsp; // Copying code here.}您的代码应该做什么?首先,创建该对象的新实例-您可以调用[[[self class] alloc] init]以获取当前类的初始化对象,该对象对子类非常有用。然后,对于NSObject支持复制的子类的任何实例变量,可以调用[thatObject copyWithZone:zone]新对象。对于原始类型(int,char,BOOL和朋友)刚刚成立的变量是相等的。因此,对于您的目标供应商,它看起来像这样:- (id)copyWithZone:(NSZone *)zone{&nbsp; &nbsp; id copy = [[[self class] alloc] init];&nbsp; &nbsp; if (copy) {&nbsp; &nbsp; &nbsp; &nbsp; // Copy NSObject subclasses&nbsp; &nbsp; &nbsp; &nbsp; [copy setVendorID:[[self.vendorID copyWithZone:zone] autorelease]];&nbsp; &nbsp; &nbsp; &nbsp; [copy setAvailableCars:[[self.availableCars copyWithZone:zone] autorelease]];&nbsp; &nbsp; &nbsp; &nbsp; // Set primitives&nbsp; &nbsp; &nbsp; &nbsp; [copy setAtAirport:self.atAirport];&nbsp; &nbsp; }&nbsp; &nbsp; return copy;}

动漫人物

该答案与已接受的答案相似,但是使用allocWithZone:并针对ARC更新了该答案。NSZone是分配内存的基础类。尽管NSZone在大多数情况下忽略可能有效,但这仍然是不正确的。为了正确实现,NSCopying您必须实现一种协议方法,该方法分配具有与原始值匹配的属性的对象的新副本。在标题的接口声明中,指定您的类实现了该NSCopying协议:@interface Car : NSObject<NSCopying>{&nbsp;...}在.m实现中,添加一个-(id)copyWithZone类似于以下内容的方法:- (id)copyWithZone:(NSZone*)zone{&nbsp; &nbsp; Car* carCopy = [[[self class] allocWithZone:zone] init];&nbsp; &nbsp; if (carCopy)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; carCopy.isAvailable = _isAvailable;&nbsp; &nbsp; &nbsp; &nbsp; carCopy.transmissionType = _transmissionType;&nbsp; &nbsp; &nbsp; &nbsp; ... // assign all other properties.&nbsp; &nbsp; }&nbsp; &nbsp; return carCopy;}

绝地无双

只需调用object.copy()即可创建副本。我没有使用copy()过值类型,因为它们是“自动”复制的。但是,我不得不使用copy()的class类型。我忽略了该NSZone参数,因为文档称它已弃用:该参数被忽略。存储区不再由Objective-C使用。另外,请注意,这是一个简化的实现。如果您有子类,它会变得有些棘手,您应该使用动态类型:type(of: self).init(transmissionType: transmissionType)。class Vendor {&nbsp; &nbsp; let vendorId: String&nbsp; &nbsp; var availableCars: [Car] = []&nbsp; &nbsp; init(vendorId: String) {&nbsp; &nbsp; &nbsp; &nbsp; self.vendorId = vendorId&nbsp; &nbsp; }}extension Vendor: NSCopying {&nbsp; &nbsp; func copy(with zone: NSZone? = nil) -> Any {&nbsp; &nbsp; &nbsp; &nbsp; let copy = Vendor(vendorId: vendorId)&nbsp; &nbsp; &nbsp; &nbsp; if let availableCarsCopy = availableCars.map({$0.copy()}) as? [Car] {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; copy.availableCars = availableCarsCopy&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; return copy&nbsp; &nbsp; }}class Car {&nbsp; &nbsp; let transmissionType: String&nbsp; &nbsp; var isAvailable: Bool = false&nbsp; &nbsp; var fees: [Double] = []&nbsp; &nbsp; init(transmissionType: String) {&nbsp; &nbsp; &nbsp; &nbsp; self.transmissionType = transmissionType&nbsp; &nbsp; }}extension Car: NSCopying {&nbsp; &nbsp; func copy(with zone: NSZone? = nil) -> Any {&nbsp; &nbsp; &nbsp; &nbsp; let copy = Car(transmissionType: transmissionType)&nbsp; &nbsp; &nbsp; &nbsp; copy.isAvailable = isAvailable&nbsp; &nbsp; &nbsp; &nbsp; copy.fees = fees&nbsp; &nbsp; &nbsp; &nbsp; return copy&nbsp; &nbsp; }}
打开App,查看更多内容
随时随地看视频慕课网APP