实现NSCopying

我已经阅读了NSCopying文档,但是我仍然不确定如何实现所需的东西。

我的class级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个其他自定义对象的数组。

VendorCar都是从字典中初始化的。 我将添加这些方法之一,它们可能会或可能不相关。

 -(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]; self.venLocationName = [[[vehVendorAvails objectForKey:@"Info"] objectForKey:@"LocationDetails"] objectForKey:@"@Name"]; self.venAddress = [[[[vehVendorAvails objectForKey:@"Info"] objectForKey:@"LocationDetails"] objectForKey:@"Address"] objectForKey:@"AddressLine"]; self.venCountryCode = [[[[[vehVendorAvails objectForKey:@"Info"] objectForKey:@"LocationDetails"] objectForKey:@"Address"] objectForKey:@"CountryName"] objectForKey:@"@Code"]; self.venPhone = [[[[vehVendorAvails objectForKey:@"Info"] objectForKey:@"LocationDetails"] objectForKey:@"Telephone"] objectForKey:@"@PhoneNumber"]; availableCars = [[NSMutableArray alloc] init]; NSMutableArray *cars = (NSMutableArray *)[vehVendorAvails objectForKey:@"VehAvails"]; for (int i = 0; i < [cars count]; i++) { Car *car = [[Car alloc] initFromVehicleDictionary:[cars objectAtIndex:i]]; [availableCars addObject:car]; [car release]; } self.venLogo = [[[vehVendorAvails objectForKey:@"Info"] objectForKey:@"TPA_Extensions"] objectForKey:@"VendorPictureURL"]; return self; } 

所以总结一下这个可怕的问题。

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

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

要实现NSCopying ,您的对象必须响应-copyWithZone:select器。 以下是你如何声明你遵守它:

 @interface MyObject : NSObject <NSCopying> { 

然后,在你的对象的实现(你的.m文件)中:

 - (id)copyWithZone:(NSZone *)zone { // Copying code here. } 

你的代码应该做什么? 首先,创build一个对象的新实例 – 你可以调用[[[self class] alloc] init]来获得当前类的初始化对象,这对于子类化来说很好。 然后,对于任何支持复制的NSObject子类的实例variables,可以为新对象调用[thatObject copyWithZone:zone] 。 对于原始types( intcharBOOL和friends),只需将variables设置为相等即可。 所以,对于你的obejct供应商,它看起来像这样:

 - (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; } 

这个答案类似于接受,但使用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; }