资讯专栏INFORMATION COLUMN

Swift中的文件和初始化

shenhualong / 2596人阅读

摘要:文件和初始化到目前为止,大多数开发者已经可以写出简单的应用或者在实验语言的新特性。本文首发地址中的文件和初始化

文件和初始化

到目前为止,大多数开发者已经可以写出简单的Swift应用或者在Playground实验Swift语言的新特性。也许你也经历过这种情况,当你将Playground中运行正常的代码拷贝到Swift源文件中却发生了编译错误,“这到底是怎么回事?Playground文件和Swift源文件之间到底有什么不同?” 这篇文将告诉你们如何处理Swift项目中的各种文件,以及如何初始化全局数据。

应用中的文件

一个Swift应用必定会包含很多个源文件,基本上每个源文件中都有构成该应用的函数、类和其他一些申明等。Swift应用中的大多数源文件都是不需要按顺序访问的,都是无顺序的,你甚至可以在某个模块的最底部导入需要的源文件(虽然Swift不推荐这种编码风格)。

不管怎样,在大多数Swift的源文件中是不允许有最顶层级别的代码的。这里解释一下顶层代码,任何写在函数体、类之外,或被封装供他人调用的可执行语句我们称为顶层代码。我们之所以不允许出现顶层代码,是因为它会影响我们判断程序是从哪里开始运行的。

Playground,REPL,顶层代码

你可能会奇怪,为什么下面的代码在Playground中可以完美执行。由于它并没有包含任何其他东西,所以它必然是顶层代码:

println("Hello world")

上面的单行程序在没有任何其他代码的情况就可以正常运行,是因为Playground支持执行顶层代码。并且在Playground中引入的文件或者代码是按自上而下的顺序执行的。比如说,你不能在定义某个类型之前去使用它。当然,在Swift的Playground中也可以定义函数、类和其他在Swift中合法的任何类型,但并没有必要这么做。Playground的目的在于让开发者们能更简单、更快速的学习Swift语言和实验新的API,而不用创建大量Swift源文件去做这些事。

除了Playground,顶层代码也可以在REPL(Read-Eval-Print-Loop)中运行或作为脚本在Swift文件启动时运行。通过脚本使用Swift时,你可以在终端中用#!/usr/bin/xcrun swift或者xcrun swift myFile.swift的方式使用Swift文件。

应用程序的入口与“main.swift”

你可能也注意到了,在上面的文章中,我们提到在大多数的源文件中是不允许使用顶层代码的。但对一个文件除外,那就是main.siwft文件,该文件的作用类似于Playground,但是它是随着你应用的其他源文件一起编译的。main.swift文件中允许顶层代码并且执行顺序是自上而下的。实际上,main.siwft文件中的第一行代码就默认为是程序的入口。正因为如此,所以我们才能看到在Swift最小的程序只有一行代码,但它必须要在main.swift文件中。

在Xcode中,Mac程序模板文件中就包含一个main.swift文件,但在iOS程序的项目模板中是通过在Swift文件中添加@UIApplicationMain标签注明项目入口的。这样做会让编译器忽略main.swift入口文件,而将标注有@UIApplicationMain标签的文件当做入口文件。

全局变量

我们已经知道了Swift是如何判断程序的执行入口,那么全局变量是如何工作的呢?下面的这行代码,在运行时需要初始化吗?

var someGlobal = foo()

在单文件的程序中,代码是自上而下执行的,这类似于函数中变量的执行方式。这虽然看起来很简单,但是在复杂的程序中我们就不是很好回答这个问题了。我们从下面三个方面来考虑:

限制初始化,像简单的常量表达式,比如C语言。

任意初始化,在应用程序加载执行静态构造函数时初始化,比如C++语言。

延迟初始化,当全局变量第一次被使用的时候初始化,比如Java语言。

我们基本排除第一种情况,因为在Swift中不需要像C语言中的常量表达式。在Swift中,常量通常是在函数调用的时候执行的(内联)。而且也有更好的理由使用复杂的初始化方法,比如设置一个单例或者实例化一个字典。

第二种情况我们也基本排除,因为它在大型、复杂的程序中的效率很差。因为所有的初始化都要在应用程序启动之前,但是我们无法预测初始化的顺序,所以会有问题。

Swift采用第三种情况,这是最好的方法:允许自定义初始化,在程序启动时不会因为要进行大量初始化而降低效率,并且我们也可以预知每次初始化完成的顺序。

延迟初始化的全局变量(也包括结构体和枚举中的静态成员)是在第一次访问他们的时候才初始化的,并且以dispatch_once运行,确保了线程安全。你可以更酷的使用dispatch_once:只需要申明一个全局变量并初始化,再将其访问级别申明为private

总结

Swift语言的设计使得它可以很方便的在Playground中进行试验或快捷的编写脚本。一个完整的程序可以只有一行代码。当然,你也可以使用Swift编写出各种复杂的应用程序。你可以通过main.swift掌控各种初始化的完成时机,或者通过@UIApplicationMain标签指定你的iOS应用的程序入口。

本文首发地址:Swift中的文件和初始化

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/15530.html

相关文章

  • 【译】哥们儿,我的方法哪儿去了?

    摘要:原文链接译文原链译哥们儿,我的方法哪儿去了想象有一天你正在给编译器喂一些看起来无害的代码。有一些重命名相当轻微,比如中的这个在这里从方法名里移除了。编译器只能自动重命名,因为其遵循良好的系统命名法。 原文链接:Dude, Wheres my Call?译文原链:【译】哥们儿,我的方法哪儿去了? 想象有一天你正在给 Swift 编译器喂一些看起来无害的代码。 // xcrun -sdk ...

    Brenner 评论0 收藏0
  • swift中的声明关键字详解

    摘要:原起学习,中的关键字当然要了解清楚了,最近在网上看到了关于声明关键字的文章,整理记录一下。常见的关键字有以下种与声明有关的关键字和。在特定上下文中使用的关键字和。参考中的关键字详解 原起 学习swift,swift中的关键字当然要了解清楚了,最近在网上看到了关于声明关键字的文章,整理记录一下。 关键字是类似于标识符的保留字符序列,除非用重音符号(`)将其括起来,否则不能用作标识符。关键...

    MadPecker 评论0 收藏0
  • 从Java到Swift

    摘要:函数的定义形如函数可以返回多个返回值,这个功能真是太猛了。支持函数类型,根据输入参数和返回值确定一个函数类型。例如函数的参数可以另外一个函数,注意,不是另外一个函数的返回值,而是另外一个函数,只要类型符合即可。 我们学习的新事物时,通常并不是从0开始,而是从已知开始,将新事物与已知的进行比较分析,从而快速全面地了解新事物。而我熟悉Java,所以在学习Swift时,就会将Swift与Ja...

    lemon 评论0 收藏0
  • Swift 新特性 - 访问控制(Access Control)

    摘要:模块和源文件中的访问控制模型基于模块和源文件这两个概念。如果在或者级别的类型中定义嵌套类型,那么该嵌套类型自动拥有访问级别。如果想让嵌套类型拥有访问级别,那么需要对该嵌套类型进行明确的访问级别申明。子类子类的访问级别不得高于父类的访问级别。 苹果在发布了Xcode 6 Bate 4后为Swift添加了新的特性--访问控制(Access Control),并且更新了The Swift P...

    binta 评论0 收藏0
  • TestBird 崩溃分析(Artisan) iOS SDK 使用指南

    摘要:最新版本更新内容支持插件,收集异常支持语言一快速集成崩溃分析,支持及以上版本。上传符号化文件将符号化文件压缩成包,通过崩溃分析应用设置中的版本管理上传。手动上报的将单独显示在分析报表的异常栏目中。 最新版本1.04 更新内容 支持H5插件,收集H5 JS异常; 支持Swift语言 一、快速集成 TestBird 崩溃分析(Artisan) iOS SDK,支持iOS 6.0 及以上版...

    Null 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<