更具体地说,即使继承了所有其他便利性,imageNamed也不会暴露给NSImage的Swift子类。
根据Apple的文档,Objective-C工厂方法“在Swift中被映射为便利初始化器。”
因此NSImage工厂方法
+ (NSImage *)imageNamed:(NSString *)name
被映射到Swift的
NSImage(named: "anything")
另外,在Swift Programming Language一书中,我们看到子类初始化器继承的规则是:
“规则1 如果您的子类没有定义任何指定的初始值设定项,它会自动继承其所有超类指定的初始值设定项。
规则2 如果您的子类提供了所有超类指定初始化程序的实现 - 通过按照规则1继承它们,或者通过提供自定义实现作为其定义的一部分 - 那么它会自动继承所有超类便利初始化程序。“
因此遵循子类
class T : NSImage {
}
将继承所有超类'初始值设定项,既指定又方便,但以下内容不起作用
let I = T(named: "anything")
我错过了什么?
答案 0 :(得分:3)
原因似乎是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
的实例,但如果你这样做了不提供您自己的实现,将调用超类实现,正如我们在声明中看到的,它返回NSImage
。
为什么它与所有其他初始值设定项不同?我不知道。
也许NSImage
使用的底层实现和缓存机制导致了这种不一致。但更重要的是,+[NSImage imageNamed:]
不会调用任何NSImage
指定的初始值设定项。
看看这个例子,我用Cocoa Touch UIImage
UIImage
https://gist.github.com/bartekchlebek/d61154add8525218ae3a
你可以在那里看到,我创建了一个名为MyImage
的{{1}}的子类,并覆盖了所有UIImage
的初始值设定项,并将NSLog
置于其中并返回零。
在
- (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不需要这样做。