gpt4 book ai didi

objective-c - Obj-C 工厂方法未暴露给 Swift 子类

转载 作者:搜寻专家 更新时间:2023-10-31 19:31:34 25 4
gpt4 key购买 nike

更具体地说,imageNamed 不会暴露给 NSImage 的 Swift 子类,即使继承了所有其他便利 init。

根据 Apple 的文档,Objective-C 工厂方法“被映射为 Swift 中的便利初始化程序。”

因此是 NSImage 工厂方法


+ (NSImage *)imageNamed:(NSString *)名称

被映射到 Swift 的


NSImage(命名为:“任何东西”)

另外,在Swift Programming Language一书中我们看到子类初始化继承的规则是:

“规则 1如果您的子类没有定义任何指定的初始化器,它会自动继承其父类(super class)的所有指定初始化器。

规则 2如果您的子类提供了其所有父类(super class)指定初始化器的实现——通过按照规则 1 继承它们,或者通过提供自定义实现作为其定义的一部分——那么它会自动继承所有父类(super class)便利初始化器。”

因此子类


T 类:NSImage {
}

将继承所有父类(super class)的初始化器,包括指定的和方便的,但以下将不起作用
让我= T(命名为:“任何东西”)

我错过了什么?

最佳答案

原因似乎是 named: 初始化器的返回类型为 NSImage

class NSImage : NSObject, NSCopying, NSCoding, NSSecureCoding, NSPasteboardReading, NSObjectProtocol, NSPasteboardWriting {

/*All instance variables are private*/

init?(named name: String) -> NSImage /* If this finds & creates the image, only name is saved when archived */

而其他(不是所有)初始化器没有返回类型

    init(size aSize: NSSize)
init?(data: NSData) /* When archived, saves contents */
init?(contentsOfFile fileName: String) /* When archived, saves contents */
init?(contentsOfURL url: NSURL) /* When archived, saves contents */
init?(byReferencingFile fileName: String) /* When archived, saves fileName */
init(byReferencingURL url: NSURL) /* When archived, saves url, supports progressive loading */

现在正因为如此,如果你有一个 T 类,它是 NSImage 的子类,你会期望 T(named:) 到返回 T 的实例,但如果您不提供自己的实现,将调用父类(super class)实现,正如我们在声明中看到的那样,它返回一个 NSImage

为什么它与所有其他初始化程序不同?我不知道。
也许 NSImage 使用的底层实现和缓存机制导致了这种不一致。但更重要的是 +[NSImage imageNamed:] 不会调用任何 NSImage 指定的初始化程序。

看看我用 Cocoa Touch 的 UIImage 制作的这个例子:https://gist.github.com/bartekchlebek/d61154add8525218ae3a

你可以在那里看到,我创建了一个名为 MyImageUIImage 子类,我覆盖了所有 UIImage 的初始化程序,将 NSLog 并返回 nil。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

我调用 -[MyImage imageNamed:] 并注意到,放置在指定初始化程序中的 NSLog 都没有被打印。我还打印了用 -[MyImage imageNamed:] 创建的实例的类,你可以看到它不是 MyImage 而是 UIImage (把除了我在所有初始化器中返回 nil 的事实之外 ;) )


总之,+[UIImage imageNamed:] 不会调用任何 UIImage 的指定初始化器,因此覆盖它们不会使 +[MyImage imageNamed:] 返回 MyImage 的实例。我希望 NSImage 的行为方式相同。

这种微妙之处导致 Swift 不继承 named: 初始化器,因为 swift 要求 便利初始化器通过指定的初始化器,而 Objective -C 没有要求。

关于objective-c - Obj-C 工厂方法未暴露给 Swift 子类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26551100/

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