在赋值时使用复制方法时未检查数据类型

时间:2011-12-09 04:48:38

标签: objective-c pointers properties protocols nscopying

我对副本有疑问

概述:

  • 我有2个班级,分别是CarMutableCar
  • 这两个类都符合协议NSCopying
  • 方法copy将返回Car
  • 的实例

问题

  1. 为什么编译器不会为以下语句抛出任何编译错误?

    MutableCar* c2 = [c1 copy];

    编译器允许我将Car *分配给MutableCar *指针变量

  2. 有没有什么办法可以防止这在编译时被忽视?

    恕我直言,这可能会导致运行时崩溃,如下例所示。

  3. 代码(在单独的文件中)

    注意事项 - 使用自动参考计数(ARC)

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

1 个答案:

答案 0 :(得分:1)

声明

-[NSObject copy]返回id,类型可分配给任何对象指针。这就是为什么你没有收到错误或警告。

如果您在copy中覆盖@interface Car,声明它返回Car *,则会在您的虚假作业中收到编译器警告。