【问题标题】:Type of property does not match type of accessor (when subclassing)属性类型与访问器类型不匹配(子类化时)
【发布时间】:2012-11-23 14:02:46
【问题描述】:

好的,我知道这个主题之前在 SO 上已经多次提及,但是在检查了几个这样的问题之后,没有人谈到我在覆盖子类中的基类 getter/setter 时遇到的问题。

我的基类是:

#import <Foundation/Foundation.h>
@interface BaseClass : NSObject
@property (nonatomic, assign) int value;
@end

@implementation BaseClass
@synthesize value;
@end

因此,我希望子类充当垫片并将“值”从 int 映射到子类中的枚举:

#import <UIKit/UIKit.h>
#import "BaseClass.h"

typedef enum {
    zero = 0,
    one,
    two,
    three,
    four
} NumberEnum;

@interface ChildClass : BaseClass
-(void)setValue:(NumberEnum)newValue;
-(NumberEnum)value;
@end

@implementation ChildClass

-(void)setValue:(NumberEnum)newValue
{
    [super setValue:(int)newValue];
    NSLog(@"Child Setter");
}

-(NumberEnum)value
{
    NSLog(@"Child Getter");
    return (NumberEnum)[super value];
}

@end

我使用以下代码测试此代码:

ChildClass* fred = [[ChildClass alloc] init];
NumberEnum barney;
fred.value = one;
barney = fred.value;
barney = [fred value];

XCode (4.5.2) 生成警告

属性“值”的类型与访问器“值”的类型不匹配

在这一行

barney = fred.value;

运行代码时,我看到了 Child Setter 和 Getter 的日志消息。那么我应该怎么做才能消除这个警告,为什么我首先得到它?

【问题讨论】:

    标签: objective-c inheritance properties


    【解决方案1】:

    你的@propertyint,编译器可能弄乱了你的方法。尝试将@property 类型设置为NumberEnum,它应该可以工作(您需要将枚举定义移动到您的.h)

    【讨论】:

    • 我无法将枚举移动到基类,因为基类被用作多个子类的低音类。
    • @PeterM 那么你不能改变property的类型或者它在子类中的访问器。
    • 那么,如果您的子类处理相同属性的不同类型,即使将 int 更改为枚举数,您也可能遇到一些设计问题。也许在你的ChildClass 中创建一个新属性,然后覆盖那里的value getter/setter 方法。
    • @Ismael 基类包含可以在不同子类之间共享的通用代码,枚举基本上是一个具有预定义的一组允许值的 int。
    • 好吧,你问警告是关于什么的,就编译器而言,intNumberEnum 显然不是一回事。
    【解决方案2】:

    违规行:

    barney = fred.value;
    

    告诉编译器你想使用属性value。由于您的子类没有定义它,它会上升到基类。它发现 value 的类型不同导致警告。

    解决方案是将您的属性写为:

    @property (nonatomic, assign) int value;
    

    枚举为:

    enum {
        zero = 0,
        one,
        two,
        three,
        four
    };
    typedef int NumberEnum;
    

    这样合成的属性方法和您自己的实现使用相同的数据类型。您可以使用符号值并且没有警告。

    我建议改用 NSUInteger,因为它是 64 位友好的。

    当然,如果您只是在基类中将属性定义为NumberEnum,那就更好了。

    【讨论】:

    • fred.value 和 [fred value] 调用都通过子类中定义的 getter。我的理解是,fred.value 语法实际上是隐含 [fred value] 的语法糖,因此我希望在两行或两行都出现警告。但是我同意您的解决方案有效! (或者当然首先要继承的全部原因是我有多个子类,它们有一些我正在推入基类的公共代码)
    猜你喜欢
    • 2014-09-18
    • 2013-03-22
    • 2018-09-10
    • 1970-01-01
    • 2013-12-22
    • 1970-01-01
    • 2021-10-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多