1. ホーム
  2. iphone

[解決済み] NSCopyingの実装

2023-04-29 21:43:24

質問

私は NSCopying docs を読みましたが、要求されていることをどのように実装すればよいのか、まだ非常によくわかりません。

私のクラス 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 は辞書からのinitです。これらのメソッドのいずれかを追加します。これらは関連性があるかもしれませんし、ないかもしれません。

-(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 オブジェクトの配列をコピーする必要があります。私は NSCopying プロトコルを Vendor に実装する必要があることを意味します。 Car ということは Vendor の配列を保持します。 Car s. ということは、このクラスも Car オブジェクトに属する2つの配列に保持されるクラスにも実装する必要があるということです。

を実装する際に、何かご指導いただければ幸いです。 NSCopying プロトコルを Vendor を使用していますが、これに関するチュートリアルはどこにも見当たりません。

どのように解決するのですか?

実装方法 NSCopying を実装するためには、オブジェクトは -copyWithZone: セレクタに応答しなければなりません。以下は、それに適合していることを宣言する方法です。

@interface MyObject : NSObject <NSCopying> {

そして、あなたのオブジェクトの実装(あなたの .m ファイル) を作成します。

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

あなたのコードはどうすればいいのでしょうか?まず、このオブジェクトの新しいインスタンスを作成します。 [[[self class] alloc] init] を呼び出して現在のクラスの初期化されたオブジェクトを取得することができ、これはサブクラス化のためにうまく機能します。次に、インスタンス変数のうち、サブクラスである NSObject のサブクラスで、コピーをサポートするものであれば [thatObject copyWithZone:zone] を新しいオブジェクトのために呼び出します。プリミティブな型に対しては ( int , char , BOOL といった具合に、変数が等しくなるように設定するだけです。つまり、obejct Vendorの場合は、次のようになります。

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