gpt4 book ai didi

objective-c - 子类中的狭义属性类型

转载 作者:可可西里 更新时间:2023-11-01 05:31:31 24 4
gpt4 key购买 nike

今天我遇到了一个奇怪的行为,我没想到 Objective-C 编译器会允许。

在 UITableViewCell 中,有一个 UIImageView 类型的名为 imageView 的属性。我对 UITableViewCell 进行了子类化,并覆盖了 imageView,只是我将其设为 AWImageView 类型,其中 AWImageView 是 UIImageView 的子类。我以为它不会编译,但它会。一切正常。我对这种行为感到非常震惊。

官方允许缩小子类中的属性类型吗?还是这是 Objective-C 编译器中的一个错误?

最佳答案

你对被允许这样做的怀疑是有根据的,但在这种特殊情况下你没问题......

在覆盖的严格子类型解释中,覆盖方法可以接受更通用类型的参数并返回更具体类型的值。

例如,使用 Objective-C,给定:

@interface A : NSObject { ... }
@interface B : A { ... }
@interface C : B { ... }

和B中的方法M:

- (B *) M:(B *)arg { ... }

然后在严格子类型化的 C 类中,这可以在 C 类中使用以下方法覆盖:

- (C *) M:(A *)arg { ... }

这是安全的,因为如果你有一个明显的 B 对象的引用:

B *bObj = ...;

然后方法 M 调用:

B *anotherBObj = [bObj M:[B new]];

那么无论 bObj 实际上是 B 还是 C,调用的类型都是正确的 - 如果它是 C 对象,那么参数是 B 就很好,因为它也是 A,结果是一个 C 很好,因为它也是一个 B。

这让我们不完全来到了您的属性(property);在 Objective-C 中,属性只是两种方法的简写:

@property B *myBvalue;

是以下内容的简写:

- (void) setMyBvalue:(B *)value;
- (B *) myBvalue;

如果该属性在 B 中声明,并且您在类 C 中使用 C 值属性覆盖它:

@property C *myBvalue;

你得到:

- (void) setMyBvalue:(C *)value;
- (C *) myBvalue;

并且方法 setMyBvalue: 违反了严格的子类型化规则 - 将 C 实例转换为 B 实例并且类型化规则说您可以传递 B,该方法需要一个 C,然后可能会出现困惑.

但是在您的情况下,您覆盖的属性是readonly,因此没有setter,也没有危险。

关于objective-c - 子类中的狭义属性类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10711755/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com