我已经阅读了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;
@endVendor类有一个名为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对象的两个数组中的类上实现它。
如果我能得到一些关于在Vendor上实现NSCopying协议的指导,我将不胜感激,我在任何地方都找不到任何关于这方面的教程。
发布于 2010-11-04 00:42:42
要实现NSCopying,您的对象必须响应-copyWithZone:选择器。下面是你如何声明你符合它:
@interface MyObject : NSObject <NSCopying> {然后,在对象的实现( .m文件)中:
- (id)copyWithZone:(NSZone *)zone
{
// Copying code here.
}你的代码应该做什么?首先,创建一个新的对象实例--你可以调用[[[self class] alloc] init]来获得当前类的一个初始化的object,这对于子类化很有效。然后,对于作为支持复制的NSObject子类的任何实例变量,您可以为新对象调用[thatObject copyWithZone:zone]。对于原始类型(int、char、BOOL和friends),只需将变量设置为相等即可。因此,对于您的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;
}发布于 2017-01-04 01:19:35
此答案类似于已接受的答案,但使用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;
}发布于 2018-01-09 00:38:25
Swift版本
只需调用object.copy()来创建副本。
我没有对值类型使用copy(),因为这些值类型是“自动”复制的。但是我不得不对class类型使用copy()。
我忽略了NSZone参数,因为docs说它已被弃用:
忽略此参数。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
}
}https://stackoverflow.com/questions/4089238
复制相似问题