首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >实现NSCopying

实现NSCopying
EN

Stack Overflow用户
提问于 2010-11-04 00:28:19
回答 2查看 56.2K关注 0票数 86

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

我的类Vendor

代码语言:javascript
复制
@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对象:

代码语言:javascript
复制
@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都是从字典中初始化的。我将添加其中一个方法,它们可能是相关的,也可能是无关的。

代码语言:javascript
复制
-(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协议的指导,我将不胜感激,我在任何地方都找不到任何关于这方面的教程。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-11-04 00:42:42

要实现NSCopying,您的对象必须响应-copyWithZone:选择器。下面是你如何声明你符合它:

代码语言:javascript
复制
@interface MyObject : NSObject <NSCopying> {

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

代码语言:javascript
复制
- (id)copyWithZone:(NSZone *)zone
{
    // Copying code here.
}

你的代码应该做什么?首先,创建一个新的对象实例--你可以调用[[[self class] alloc] init]来获得当前类的一个初始化的object,这对于子类化很有效。然后,对于作为支持复制的NSObject子类的任何实例变量,您可以为新对象调用[thatObject copyWithZone:zone]。对于原始类型(intcharBOOL和friends),只需将变量设置为相等即可。因此,对于您的obejct,它将如下所示:

代码语言:javascript
复制
- (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;
}
票数 187
EN

Stack Overflow用户

发布于 2017-01-04 01:19:35

此答案类似于已接受的答案,但使用allocWithZone:并针对ARC进行更新。NSZone是分配内存的基础类。虽然忽略NSZone在大多数情况下可能有效,但它仍然是不正确的。

要正确实现NSCopying,您必须实现一个协议方法,该方法分配对象的新副本,其属性与原始值匹配。

在标头的接口声明中,指定您的类实现NSCopying协议:

代码语言:javascript
复制
@interface Car : NSObject<NSCopying>
{
 ...
}

在.m实现中,添加如下所示的-(id)copyWithZone方法:

代码语言:javascript
复制
- (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;
}
票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4089238

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档