I have a doubt regarding copy
Overview:
- I have 2 classes namely
CarandMutableCar - Both these classes conform to the protocol
NSCopying - The method
copywould return an instance ofCar
Question
-
Why doesn’t the compiler doesn’t throw any compilation error for the following statement?
MutableCar* c2 = [c1 copy];The compiler allows me to assign Car* to a MutableCar* pointer variable
-
Is there any way that this can be prevented from going unnoticed at compile time?
IMHO this could lead to crashes at runtime as shown in the example below.
Code (in separate files)
Points to note – Automatic Reference Counting (ARC) is used
Car.h
#import<Foundation/Foundation.h>
@interface Car : NSObject <NSCopying>
@property (readonly) int n1;
@end
Car.m
#import"Car.h"
#import"MutableCar.h"
@interface Car() //extension
@property (readwrite) int n1;
@end
@implementation Car
@synthesize n1 = _n1;
- (id) copyWithZone: (NSZone*) pZone
{
Car* newInstance = [[Car alloc] init];
newInstance -> _n1 = _n1;
return(newInstance);
}
@end
MutableCar.h
#import"Car.h"
@interface MutableCar : Car
@property int n1; // redeclaration
@property int n2;
@end
MutableCar.m
#import"MutableCar.h"
@implementation MutableCar
@dynamic n1;
@synthesize n2 = _n2;
@end
test.m
#import"MutableCar.h"
int main()
{
MutableCar* c1 = [[MutableCar alloc] init];
MutableCar* c2 = [c1 copy]; //Car* is being assigned to MutableCar* variable
//Why doesn't the compiler doesn't throw any compilation error ?
//c2.n2 = 20; //At runtime this throws an error, because c2 is not a MutableCar instance
return(0);
}
-[NSObject copy]is declared to returnid, a type is assignable to any object pointer. That’s why you don’t get an error or a warning.If you override
copyin@interface Car, declaring it to returnCar *, you’ll get a compiler warning on your bogus assignment.