Objective c Swift-目标-C荷载等级法?
在Objective-C中,Objective c Swift-目标-C荷载等级法?,objective-c,swift,Objective C,Swift,在Objective-C中,NSObject有一个名为load的类方法,该方法在第一次加载类时被调用。Swift中的等价物是什么 @implementation MyClass + (void)load { [self registerClass]; } @end 在Swift 1.2之前: override class func load() { NSLog("load"); } 编辑: 从Swift 1.2开始,您不能再覆盖load方法。查看方法initialize相反,
NSObject
有一个名为load
的类方法,该方法在第一次加载类时被调用。Swift中的等价物是什么
@implementation MyClass
+ (void)load
{
[self registerClass];
}
@end
在Swift 1.2之前:
override class func load() {
NSLog("load");
}
编辑:
从Swift 1.2开始,您不能再覆盖
load
方法。查看方法initialize
相反,它的行为不同于load,但是它在类第一次在某处被引用时被调用,而不是在应用程序初始加载时被调用
public override class func initialize()
对于Swift 2或3(即Swift 1.2之后),您可以使用:
class MySwiftClass: NSObject {
internal override class func initialize() {
DoStuff()
super.initialize()
}
}
但是,正如您所看到的,您的类需要继承(直接或间接)表单对象。这是必需的,因为ObjC运行时调用了initialize()
而initialize()
方法只有在引用myswitclass
时才会被调用。因此,它不会像加载()那样神奇
但它也会更安全。例如:包含一个框架(比方说,只需将它添加到你的
Podfile
)不会让框架在你的应用程序启动时就神秘地开始运行,而不需要向你的项目添加一行代码(至少……我希望!更新:从Swift 5类扩展开始,Swift类上的类别不允许有+load方法,+initialize似乎不被禁止
虽然Swift不能提供直接等效,但使用Objective-C和categories可以相对优雅地实现这一点。Foo
仍应继承自NSObject
,并具有类/静态非私有swiftyLoad/Initialize
方法,这些方法可从Loader.m
中的Objective-C调用,您可以在在编译源代码时,将其与Foo.swift
放在一起:
# Loader.m
#import <Foundation/Foundation.h>
#import <MyProject/MyProject-Swift.h>
// This was a more concise solution in Swift 4.2 and earlier. If you try
// this with Swift 5 you'd get "Swift class extensions and categories
// on Swift classes are not allowed to have +load methods" runtime error.
// @implementation Foo (private)
// + (void)load { [self swiftyLoad]; }
// + (void)initialize { [self swiftyInitialize]; }
// @end
// This is what you'd want to use with Swift 5 onwards, basically
// just a pure Objective-C defined class.
@interface Loader : NSObject
@end
@implementation Loader : NSObject
+ (void)load { [Foo swiftyLoad]; }
+ (void)initialize { [Foo swiftyInitialize]; }
@end
# Foo.swift
import Foundation
public class Foo: NSObject {
@objc public static func swiftyLoad() {
Swift.print("Rock 'n' roll!")
}
@objc public static func swiftyInitialize() {
Swift.print("Hello initialize!")
}
}
#Loader.m
#进口
#进口
//这是Swift 4.2及更早版本中更简洁的解决方案
//使用Swift 5,您将获得“Swift类扩展和类别”
//在Swift类上不允许有+load方法“运行时错误。
//@Foo(私人)
//+(无效)加载{[自快速加载];}
//+(void)初始化{[自快速初始化];}
//@end
//基本上,这是您希望在Swift 5之后使用的
//只是一个纯Objective-C定义的类。
@接口加载器:NSObject
@结束
@实现加载器:NSObject
+(void)加载{[Foo-swiftyLoad];}
+(void)初始化{[Foo swiftyInitialize];}
@结束
#福斯威夫特
进口基金会
公共类Foo:NSObject{
@objc公共静态函数swiftyLoad(){
Swift.print(“摇滚乐!”)
}
@objc公共静态函数快速初始化(){
打印(“Hello initialize!”)
}
}
最好的一点是,它不需要使用桥接头或其他任何东西,它只是工作。有两个问题,特别是在静态库中使用这种方法时,请查看完整的媒体以了解详细信息!✌️ 我对swift 1.2~5种可行方法得出结论:
Doable |swift-load |swift-initialze|bridgeToOC-load|bridgeToOC-initialze|
--- |---- |--- |--- |--- |
swift1.2~4.2|X |O |O |O |
swift4.2~5.0|X |X |O |O |
swift5.0~? |X |X |X |O |
如何制作?在这里查看但我认为还有另一种方法可以使它更快。使用运行时和protol而不加载/初始化 Swift中的等价物是什么
@implementation MyClass
+ (void)load
{
[self registerClass];
}
@end
没有
与存储实例属性不同,您必须始终为存储类型属性指定默认值。这是因为该类型本身没有可以在初始化时为存储类型属性指定值的初始值设定项
资料来源:“Swift编程语言”,由苹果公司提供
类型在Swift中没有初始值设定项。正如这里的几个答案所建议的,您可以通过使用Objective-C桥并让您的Swift类继承自NSObject
或使用Objective-C loader引导代码来解决这个问题,但如果您有一个100%的Swift项目,您基本上只有两个选项:
对于特殊情况可能有更好的解决方案,但您没有提供任何信息来说明为什么您需要该特性。
注意,如果您的类从<代码> NSbObjs< /C> >,这仅适用。@代码>导入基础@ Objc类Myclass {class FUNC Load()){PrtLnn(“SDFSDF”)}。这不再有效。您将得到错误“Method'load()”定义Objective-C类方法“load”,这在NSObject子类的Swift“Swift 2.1:内部重写类func initialize(){}
中是不允许的。我没有找到initialize()在纯Swift对象中允许使用
。Swift中不再允许重写初始化。@VladimirKofman它将在第一次使用类时被调用,这不一定是在加载时。但是类必须是@objc
。NSObject
noo:(这在swift5中不再有效。一段时间前已为Swift 5更新了Medium post。我在几个生产应用程序中使用了它。还更新了答案,请再试一次。
class MyCoolClass {
private static var classInitialized: Bool = {
// Do your init stuff here...
// This code will for sure only run once!
return true
}()
private static func ensureClassIsInitialized ( ) {
_ = self.classInitialized
}
func whateverA ( ... ) {
MyCoolClass.ensureClassIsInitialized()
// Do something...
}
func whateverB ( ... ) {
MyCoolClass.ensureClassIsInitialized()
// Do something...
}
func whateverC ( ... ) {
MyCoolClass.ensureClassIsInitialized()
// Do something...
}
}