【问题标题】:Can a subclass add parameters in a block in a parameter in an inherited method?子类可以在继承方法的参数中的块中添加参数吗?
【发布时间】:2014-01-13 00:11:05
【问题描述】:

情况

超类定义方法,子类重新定义该方法。唯一不同的是子类在block中增加了一个参数,这个参数本身就是方法的参数。

一个例子

想象一下,我有一个类 Collection 和一个后代类 List,它们在 NSArray 样式中定义了一个枚举方法(以及其他方法)。

@interface Collection : NSObject
- (void)enumerateObjectsUsingBlock: (void (^)(id obj))block;
@end

@interface List : Collection
- (void)enumerateObjectsUsingBlock: (void (^)(id obj, int index))block;
@end

问题

这是否有效(在所有平台上)并且符合标准?

我想它会起作用,因为超类方法中的参数列表不受影响,而子类方法的用户会知道(可选地通过一些类型转换)额外的参数。

【问题讨论】:

  • 由于 Objective-C 中的所有方法都是虚拟的,因此应该可以正常工作。
  • @YasKuraishi 基本的 Objective-C 部分(忽略块参数)永远不会抱怨,因为块是 id-等价的。我的问题是:这两种不同的块类型是否兼容(或协变)?
  • 我相信他们是这样的,这样应该可以正常工作并打印从obj 参数中的List 方法传递的内容,因为您在Collection 变量上调用它,因此@987654329 @param 将被忽略:Collection *coll = [List new]; [coll enumerateObjectsUsingBlock:^(id obj) { NSLog(@"obj from List: %@", obj); }];
  • @YasKuraishi 如果有效,那只是巧合。

标签: objective-c inheritance methods objective-c-blocks overriding


【解决方案1】:

简而言之;不,不要这样做。

更长:

它适用于大多数情况,但您必须努力避免编译器警告。 Objective-C 不支持方法的协变或反变声明(这就是创建 instancetype 的原因)。由于块类型不同,方法参数类型也不同。

您也不能假设采用(a)、(a,b), (a,b.c)、(a,b,c,d) 等的函数、块或方法将在调用站点兼容。 IE。你不能说 fun(a,b,c,d) 哪里 fun 实际上是 fun(a) 并保证你会得到你所期望的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-19
    • 1970-01-01
    • 2019-10-08
    • 1970-01-01
    相关资源
    最近更新 更多