57

My application crashed with the reason:

-[MyClassName copyWithZone:] unrecognized selector sent to instance

I have two classes. Let's say Class1 and Class2.

Class1 looks like:

Class1.h

@interface Class1 : NSObject {
    NSString *imagemd5CheckSum;
    UIImage *image;
    NSData *fileChunkData;
}

@property (nonatomic, copy)NSString *imagemd5CheckSum;
@property (nonatomic, copy)UIImage *image;
@property (nonatomic, copy)NSData *fileChunkData;

@end

Class1.m

@implementation Class1

@synthesize image;
@synthesize fileChunkData;
@synthesize imagemd5CheckSum;

-(id) init{
    [self setImage:nil];
    [self setFileChunkData:nil];
    [self setImagemd5CheckSum:@""];

    return self;
}

-(void)dealloc{
    [imagemd5CheckSum release];
    [image release];
    [fileChunkData release];

    fileChunkData = nil;
    imagemd5CheckSum = nil;
    image = nil;

    [super dealloc];
}
@end

**

Class2 looks like

**

Class2.h


#import "Class2.h"
@interface Class2 : NSObject {
    Class1 *obj1;
    Class1 *obj2;
    Class1 *obj3;
}

@property (nonatomic, copy)Class1 *obj1;
@property (nonatomic, copy)Class1 *obj2;
@property (nonatomic, copy)Class1 *obj3;

@end

Class2.m


@implementation Class2

@synthesize obj1,obj2,obj3;

-(id) init{
    [self setObj1:nil];
    [self setObj2:nil];
    [self setObj3:nil];

    return self;
}

-(void)dealloc{
    [obj1 release];
    [obj2 release];
    [obj3 release];

    obj1 = nil;
    obj2 = nil;
    obj3 = nil;

    [super dealloc];
}
@end

Crashed Situation

Class2 *class2 = [[Class2 alloc] init];

Class1 *class1 = [[Class1 alloc] init];

[class1 setImagemd5CheckSum:@"this is md5"];
[class1 setImage:myimage];
[class1 setFileChunkData:myData];

[class2 setObj1:class1]; // This line is crashed..

...

When I called [class2 setObj1:class1];, the application crashed with reason:

-[Class1 copyWithZone:] unrecognized selector sent to instance

How can I fix this problem?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Shamsudheen TK
  • 30,739
  • 9
  • 69
  • 102

2 Answers2

76

Your -setObj1: method is declared as copy, so it calls -copy on your Class1 object. -copy just calls -copyWithZone:nil. So you either need to implement the NSCopying protocol (which means implementing -copyWithZone:), or change your property from copy to retain.

Wevah
  • 28,182
  • 7
  • 83
  • 72
53

To make your class respond to copyWithZone:, you have to implement the NSCopying protocol in your class. And you must override the copyWithZone: method.

For example:

First you have to implement the NSCopying protocol in your interface declaration.

@interface MyObject : NSObject <NSCopying>

Then override the copyWithZone method like,

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

I am glad if this helps you.

(Reference)

Community
  • 1
  • 1
Mathew Varghese
  • 4,527
  • 2
  • 17
  • 26
  • 2
    i think the fact that the zone argument is [deprecated](http://stackoverflow.com/questions/7934142/why-zone-is-allway-nil-while-implementing-nscopying) must be mentioned in this discussion – abbood Feb 17 '13 at 11:18
  • 20
    hey man.. did you copy your code from [this](http://stackoverflow.com/a/4089372/766570) answer? what is this airport and car stuff all about? – abbood Feb 17 '13 at 11:23
  • 3
    Look at the added reference. You will find out where airport and car stuff's all about. – P Griep Feb 21 '14 at 10:31