Swift中全局初始化与viewDidLoad初始化之间是否有区别 [英] Is there a difference between global Initialization vs viewDidLoad initialization in Swift

查看:225
本文介绍了Swift中全局初始化与viewDidLoad初始化之间是否有区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我有一个类,并像这样初始化变量:

If I have a class and initialize a variable like so:

class TestClass: UIViewController {
    var thisInt: Int = 10
}

与初始化类似,有什么不同

is that any different than initializing like so:

class TestClass: UIViewController {
    var thisInt: Int!

    override func viewDidLoad() {
        super.viewDidLoad()
        thisInt = 10
    }
}

我想我的主要问题在于何时进行全局初始化,并且在某个时候,在正常的iOS编程下,一个被调用的次数要多于另一个被调用的次数(不对本地开发进行任何大动作).我确实知道在viewDidLoad中执行此操作会限制我使用弱函数或可选函数,但是我更担心其他任何差异.

I suppose my main questions lie in when the global initialization takes place, and is there a time when one would get called more than the other would be called with normal iOS Programming (not doing anything drastically against native development). I do understand that doing it in viewDidLoad restricts me to using weak or an optional, but I'm more concerned about any other differences.

推荐答案

您可以通过在视图控制器中添加计算"属性来轻松地找出答案:

You can find out easily by adding a "computed" property to your view controller:

class TestClass: UIViewController {
    let a = {()->Int in print("global initialization"); return 10 }()
}

并添加一个

print("didFinishLaunching")

在应用程序的委托didFinishLaunchingWithOptions方法中.

in app's delegate didFinishLaunchingWithOptions method.

您将获得的订单是

global initialization
didFinishLaunching

这意味着全局初始化程序将在应用程序生命周期开始之前运行.

which means global initializers run before the app lifecycle begins.

现在,要走得更远,您可以添加具有以下内容的main.swift文件

Now, to go even further, you could add a main.swift file with the following contents

print("Before UIApplicationMain")

UIApplicationMain(CommandLine.argc, unsafeBitCast(CommandLine.unsafeArgv, to: UnsafeMutablePointer<UnsafeMutablePointer<Int8>>.self), nil, NSStringFromClass(AppDelegate.self))

,然后从您的AppDelegate类中移除(或注释)@UIApplicationMain装饰.这将指示编译器使用main.swift中的代码进行应用程序初始化,而不是装饰器在讨论中提供的默认行为(尽管我们提供的是定制的几乎相同的实现).

and remove (or comment) the @UIApplicationMain decoration from your AppDelegate class. This will instruct the compiler to use the code in main.swift for the application initialization instead of the default behavior provided by the decorator in discussion (although we're providing a custom almost identical implementation).

您将在第二种方法中得到

What you'll get in this 2nd approach is

Before UIApplicationMain
global initialization
didFinishLaunching

这意味着实例属性代码在加载情节提要时执行.

which means that the instance property code is executed when the storyboard is loaded.

现在,为了获得更多信息,让我们尝试找出静态实例变量之间的区别.为此,我们将添加一个测试类:

Now, for more insight, let's try to find out the differences between static an instance variables. For this we'll add a test class:

class PropertyInitializationTest {
    static let staticProp = {()->String in print("static initialization of InitializationTest"); return "" }()
    let instanceProp = {()->String in print("instance initialization of InitializationTest"); return "" }()

    init() {
        print("In initializer")
    }
}

,并完成了AppDelegate的更新的启动:

, and update AppDelegate's did finish launching:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        print("didFinishLaunching")
        print("before instantiating InitializationTest")
        _ = PropertyInitializationTest()
        print("after instantiating InitializationTest")
        // Override point for customization after application launch.
        return true
    }

我们得到的输出是:

Before UIApplicationMain
global initialization
didFinishLaunching
before instantiating InitializationTest
instance initialization of InitializationTest
In initializer
after instantiating InitializationTest

,这证实了在实例化类时以及在运行任何初始化程序代码之前设置实例属性的事实.

, which confirms the fact that instance properties get set when the class is instantiated, and before any initializer code runs.

但是等等!静态属性呢?没有任何痕迹表明它已被初始化.看起来静态属性在定义上是懒惰的,并且只有在第一次访问时才被初始化.

But wait! What about the static property? There are no traces to indicate that it was initialized at all. Looks like static properties are lazy by definition, and get initialized only when accessed the first time.

更新应用程序确实完成了启动代码,确认了这一点.

Updating the app did finish launching code confirms this.

print("didFinishLaunching")
print("before instantiating InitializationTest")
_ = PropertyInitializationTest()
print("after instantiating InitializationTest")
_ = PropertyInitializationTest.staticProp
print("after instantiating InitializationTest")

给出以下输出:

Before UIApplicationMain
global initialization
didFinishLaunching
before instantiating InitializationTest
instance initialization of InitializationTest
In initializer
after instantiating InitializationTest
static initialization of InitializationTest
after instantiating InitializationTest

总结:

  • 实例属性在类初始化程序运行之前(即在该类中的任何代码执行之前)接收编译时值(如果已设置)
  • 静态属性仅在首次访问时才接收其值,它们本质上是懒惰的

这篇关于Swift中全局初始化与viewDidLoad初始化之间是否有区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆