实现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个其他自定义对象的数组。
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]; 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( int
, char
, BOOL
和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; }