www.9778.com 6

www.9778.com:Swift 3 新特性

重点虽然转移到 Scala 3,但将继续维护 Scala
2.13,以确保社区有足够的时间谨慎地过渡到 Scala 3。

File Hierarchy Standard (FHS) 定义文件和目录在通用类 UNIX®
系统上的布局。如果您的应用程序依赖于其他配置和文件,那么可能需要使用
FHS。FHS
的主要目的是为应用程序提供一个通用的位置,以查找标准配置文件。可以在
Filesystem Hierarchy Standard 的主页上找到关于 FHS
的更多信息。(参考资料 部分提供相关链接)。

附录:

【1】

www.9778.com 1

ABI 和支持的指令集

armeabi
此 ABI 适用于基于 ARM、至少支持 ARMv5TE 指令集的 CPU。
请参阅以下文档了解详情:

  • ARM
    架构参考手册
  • ARM
    架构的过程调用标准
  • ARM ELF
    文件格式
  • ARM 架构的应用二进制界面
    (ABI)
  • ARM 架构的基本平台
    ABI
  • ARM 架构的 C 库
    ABI
  • ARM 架构的 C++
    ABI
  • ARM 架构的运行时
    ABI
  • ELF System V
    应用二进制界面
  • 通用/Itanium C++
    ABI

AAPCS 标准将 EABI 定义为类似但不同 ABI 的系列。 此外,Android
还采用小字节序 ARM GNU/Linux
ABI。
此 ABI 不支持硬件辅助的浮点计算。 相反,所有浮点运算都使用编译器
libgcc.a
静态库中的软件帮助程序函数。
armeabi ABI 支持 ARM 的 Thumb(亦称
Thumb-1)指令集。NDK
默认生成 Thumb 代码,除非您在
Android.mk
文件中使用 LOCAL_ARM_MODE变量指定不同的行为。

armeabi-v7a
此 ABI 可扩展 armeabi 以包含多个 CPU
指令集扩展。
此 Android 特定 ABI 支持的指令扩展包括:

  • Thumb-2 指令集扩展,其性能堪比 32 位 ARM 指令,简洁性类似于
    Thumb-1。
  • VFP 硬件 FPU 指令。更具体一点,包括 VFPv3-D16,它除了 ARM 核心中的
    16 个 32 位寄存器之外,还包含 16 个专用 64 位浮点寄存器。

v7-a ARM 规格描述的其他扩展,包括 高级
SIMD(亦称
NEON)、VFPv3-D32ThumbEE,都是此 ABI 可选的。
由于不能保证它们存在,因此系统在运行时应检查扩展是否可用。
如果不可用,则必须使用替代代码路径。此检查类似于系统在检查或使用
MMX、SSE2
及 x86 CPU 上其他专用指令集时所执行的检查。

如需了解有关如何执行这些运行时检查的信息,请参阅 cpufeatures
库。另外,有关
NDK 支持为 NEON 构建机器代码的信息,请参阅 NEON
支持。

armeabi-v7a ABI 使用
-mfloat-abi=softfp开关强制实施规则,要求编译器在函数调用时必须传递核心寄存器对中的所有双精度值,而不是专用浮点值。
系统可以使用 FP 寄存器执行所有内部计算。 这样可极大地加速计算。

arm64-v8a
此 ABI 适用于基于 ARMv8、支持 AArch64 的 CPU。它还包含 NEON 和 VFPv4
指令集。
如需了解详细信息,请参阅 ARMv8
技术预览,并联系
ARM 了解进一步的详细信息。

x86
此 ABI 适用于支持通常称为“x86”或“IA-32”的指令集的 CPU。 此 ABI
的特性包括:

  • 指令一般由具有编译器标志的 GCC 生成,如下所示:

-march=i686 -mtune=intel -mssse3 -mfpmath=sse -m32

这些标志指向 Pentium Pro 指令集,伴随
MMX、SSE、SSE2、SSE3

SSSE3
指令集扩展。生成的代码在顶层 Intel 32 位 CPU 之间进行了均衡优化。
如需了解有关编译器标志的详细信息,特别是与性能优化相关的信息,请参阅
GCC x86
性能提示www.9778.com:Swift 3 新特性。。

  • 使用标准 Linux x86 32 位调用约定,与 SVR
    使用的约定相反。如需了解详细信息,请参阅不同 C++
    编译器和操作系统的调用约定的第
    6 节“寄存器的使用”。

ABI 不含任何其他可选的 IA-32 指令集扩展,例如:

  • MOVBE
  • SSE4 的任何变体。

您仍可使用这些扩展,只要您使用运行时功能探测来启用它们,并且为不支持它们的设备提供备用方法。
NDK 工具链假设在函数调用之前进行 16
位栈对齐。默认工具和选项强制执行此规则。
如果编写的是汇编代码,必须确保栈对齐,而且其他编译器也遵守此规则。
请参阅以下文档了解详情:

  • GCC 在线文档: Intel 386 和 AMD x86-64
    选项
  • 不同 C++
    编译器和操作系统的调用约定
  • Intel IA-32 Intel 架构软件开发者手册第 2
    卷:指令集参考
  • Intel IA-32 Intel 架构软件开发者手册第 3
    卷:系统编程指南
  • System V 应用二进制界面: Intel386
    处理器架构补充

x86_64
此 ABI 适用于支持通常称为“x86-64”的指令集的 CPU。 它支持 GCC
通常使用以下编译器标志生成的指令:

-march=x86-64 -msse4.2 -mpopcnt -m64 -mtune=intel

这些标志指向 x86-64 指令集(根据 GCC 文档),伴随
MMX、SSE、SSE2、SSE3、SSSE3、SSE4.1、SSE4.2

POPCNT
指令集扩展。 生成的代码在顶层 Intel 64 位 CPU 之间进行了均衡优化。
如需了解有关编译器标志的详细信息,特别是与性能优化相关的信息,请参阅
GCC x86
性能。
此 ABI 不含任何其他可选的 x86-64 指令集扩展,例如:

  • MOVBE
  • SHA
  • AVX
  • AVX2

您仍可使用这些扩展,只要您使用运行时功能探测来启用它们,并且为不支持它们的设备提供备用方法。
请参阅以下文档了解详情:

  • 不同 C++
    编译器和操作系统的调用约定
  • Intel64 和 IA-32 架构软件开发者手册第 2
    卷:指令集参考
  • Intel64 和 IA-32 架构软件开发者手册第 3
    卷:系统编程

mips
此 ABI 适用于基于 MIPS、至少支持 MIPS32r1 指令集的 CPU。它包含以下功能:

  • MIPS32 修订版 1 ISA
  • 小字节序
  • O32
  • 硬浮点
  • 无 DSP 应用特定的扩展

如需了解详细信息,请参阅以下文档:

  • 编程者的架构 (“MIPSARCH”)
  • ELF System V
    应用二进制界面
  • Itanium/通用 C++
    ABI

如需了解更具体的详细信息,请参阅 MIPS32
架构。常见问答请参阅
MIPS
FAQ。

mips64
此 ABI 适用于 MIPS64 R6。如需了解详细信息,请参阅 MIPS64
架构。

说到这里,苹果好像有一种让非程序员学习 Swift 意图,例如可以在 iPad
上使用 Swift 以及某些教育措施都表明了这一点。

“二进制兼容性概述”
小节讨论的最后一个例子涉及到在两个不同的处理器类型上运行相同的二进制文件:POWER5
处理器和 POWER6 处理器。POWER6 架构是 POWER5 架构的改进,同时又保持与
POWER5 兼容,这就允许您在这两个平台上运行相同的应用程序。

SO的适配

当一个应用安装在设备上,只有该设备支持的CPU架构对应的.so文件会被安装。在x86设备上,libs/x86目录中如果存在.so文件的话,会被安装,如果不存在,则会选择armeabi-v7a中的.so文件,如果也不存在,则选择armeabi目录中的.so文件(因为x86设备也支持armeabi-v7a和armeabi)。

从目前移动端CPU市场的份额数据看,ARM架构几乎垄断,所以,除非你的用户很特殊,否则几乎可以不考虑单独编译带入X86、X86_64、mips、mips64架构SO文件。除去这四个架构之后,还要带入armeabi、armeabi-v7a、arm64-v8a这三个不同类型,这对于一个拥有大量SO文件的应用来说,安装包的体积将会增大不少。

针对以上情况,我们可以应用的设备分布和市场情况再进行取舍斟酌,如果你的应用仍有不少armeabi类型的设备,可以考虑只保留armeabi目录下的SO文件(万金油特性)。但是,尽管armeabi可以兼容多种平台,仍有些运算在armeabi-v7a、arm64-v8a,去使用armeabi的SO文件时,性能会非常差强人意,所以还是应该用其对应平台架构的SO文件进行运算。

注意:
这里并不是要带多一整套SO文件到不同的目录下,而是将性能差异比较明显的某个armeabi-v7a、arm64-v8a平台下的SO文件放到armeabi目录,然后通过代码判断设备的CPU类型,再加载其对应架构的SO文件,很多大厂的应用便是这么做的。你应该尽可能的提供专为每个ABI优化过的.so文件,但要么全部支持,要么都不支持:你不应该混合着使用。你应该为每个ABI目录提供对应的.so文件。
如微信的lib下虽然只有armeabi一个目录,但目录内的文件仍放着v5、v7a架构的SO文件,用于处理兼容带来的某些性能运算问题。

www.9778.com 2

微信的armeabi一个目录

总结
就目前市场份额而言,绝大部分的设备都已经是armeabi-v7a、arm64-v8a,你也可以考虑只保留armeabi-v7a架构的SO文件,这样能获得更好的性能效果。性能差异比较明显加入单的的so文件并在代码中去判断。

 

除此之外,Scala 官方还罗列了一些相关问题,包括争取在 2020
年年底之前发布第一个候选版本、如何采用类型化抽象语法树 TASTy
处理二进制兼容性问题、宏无法从 2.x 直接迁移到 3.0、以及性能、测试工具与
IDE 支持等,详情查看官方说明:

运行在本机 32 位 PowerPC 环境和 64 位 POWER 环境上的 32
位应用程序也可以实现二进制兼容性。可以在本机 Linux PowerPC 环境上执行在
64 位 Linux on POWER 系统上生成的 32
位二进制文件。能够实现这种兼容性是因为:

引入.so文件的错误

当你引入一个.so文件时,不止影响到CPU架构。从其他开发者那里可以看到一系列常见的错误,其中最多的是”UnsatisfiedLinkError”,”dlopen:
failed”以及其他类型的crash或者低下的性能:

1. 使用android-21平台版本编译的.so文件运行在android-15的设备上

使用NDK时,你可能会倾向于使用最新的编译平台,但事实上这是错误的,因为NDK平台不是后向兼容的,而是前向兼容的。推荐使用app的minSdkVersion对应的编译平台。

这也意味着当你引入一个预编译好的.so文件时,你需要检查它被编译所用的平台版本。

2. 混合使用不同C++运行时编译的.so文件

.so文件可以依赖于不同的C++运行时,静态编译或者动态加载。混合使用不同版本的C++运行时可能导致很多奇怪的crash,是应该避免的。作为一个经验法则,当只有一个.so文件时,静态编译C++运行时是没问题的,否则当存在多个.so文件时,应该让所有的.so文件都动态链接相同的C++运行时。

这意味着当引入一个新的预编译.so文件,而且项目中还存在其他的.so文件时,我们需要首先确认新引入的.so文件使用的C++运行时是否和已经存在的.so文件一致。

3. 没有为每个支持的CPU架构提供对应的.so文件

这一点在前文已经说到了,但你应该真的特别注意它,因为它可能发生在根本没有意识到的情况下。

例如:你的app支持armeabi-v7a和x86架构,然后使用Android
Studio新增了一个函数库依赖,这个函数库包含.so文件并支持更多的CPU架构,例如新增android-gif-drawable函数库:

compile ‘pl.droidsonroids.gif:android-gif-drawable:1.1.+’

发布我们的app后,会发现它在某些设备上会发生Crash,例如Galaxy
S6,最终可以发现只有64位目录下的.so文件被安装进手机。

解决方案:重新编译我们的.so文件使其支持缺失的ABIs,或者设置

ndk.abiFilters

显示指定支持的ABIs。

注意事项:如果你是一个SDK提供者,但提供的函数库不支持所有的ABIs,那你将会搞砸你的用户,因为他们能支持的ABIs必将只能少于你提供的。

4. 将.so文件放在错误的地方

我们往往很容易对.so文件应该放在或者生成到哪里感到困惑,下面是一个总结:

  • Android
    Studio工程放在jniLibs/ABI目录中(当然也可以通过在build.gradle文件中的设置jniLibs.srcDir属性自己指定)
  • Eclipse工程放在libs/ABI目录中(这也是ndk-build命令默认生成.so文件的目录)
  • AAR压缩包中位于jni/ABI目录中(.so文件会自动包含到引用AAR压缩包的APK中)
  • 最终APK文件中的lib/ABI目录中
    通过PackageManager安装后,在小于Android
    5.0的系统中,.so文件位于app的nativeLibraryPath目录中;在大于等于Android
    5.0的系统中,.so文件位于app的nativeLibraryRootDir/CPU_ARCH目录中。

5. 只提供armeabi架构的.so文件而忽略其他ABIs的

如前文提到的,所有的x86/x86_64/armeabi-v7a/arm64-v8a设备都支持armeabi架构的.so文件,因此似乎移除其他ABIs的.so文件是一个减少APK大小的好技巧。但事实上并不是:这不只影响到函数库的性能和兼容性。

x86设备能够很好的运行ARM类型函数库,但并不保证100%不发生crash,特别是对旧设备。64位设备(arm64-v8a,
x86_64,
mips64)能够运行32位的函数库,但是以32位模式运行,在64位平台上运行32位版本的ART和Android组件,将丢失专为64位优化过的性能(ART,webview,media等等)。

以减少APK包大小为由是一个错误的借口,因为你也可以选择在应用市场上传指定ABI版本的APK,生成不同ABI版本的APK可以在build.gradle中如下配置:

android {
    ... 
    splits {
        abi {
            enable true
            reset()
            include 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a' //select ABIs to build APKs for
            universalApk true //generate an additional APK that contains all the ABIs
        }
    }

    // map for the version code
    project.ext.versionCodes = ['armeabi': 1, 'armeabi-v7a': 2, 'arm64-v8a': 3, 'mips': 5, 'mips64': 6, 'x86': 8, 'x86_64': 9]

    android.applicationVariants.all { variant ->
        // assign different version code for each output
        variant.outputs.each { output ->
            output.versionCodeOverride =
                    project.ext.versionCodes.get(output.getFilter(com.android.build.OutputFile.ABI), 0) * 1000000 + android.defaultConfig.versionCode
        }
    }
 }

Swift 3 中最大的改变是标准库中在每个库中都采用了统一命名方式。API
Design
Guidleines中包含了这些规则,核心团队在构建
Swift 3
时采用了这些规则,对新手来说,这高度增强了可读性和易用性。核心团队遵循的是”好的
API 设计应当总是从调用者的角度看待问题”的原则。他们努力让 API
简单易用。不再多说,让我们开始介绍这些对你来说非常重要的改变。

共享标准库

作为一个例子,我们将仔细查看 Java 的使用如何影响应用程序开发人员。Java
中间件包备受关注,因为 Java 的平台独立性使得 Java
应用程序在数量上居高不下。不仅存在不同版本的 JDK 和不同的 JDK
提供商,还存在针对 Linux on POWER 的 32 位和 64 位 JDK。RHEL4 附带了 IBM
32-bit SDK for Linux V1.4.2。RHEL5 附带了 IBM 32-bit SDK for Linux
V1.4.2 和 IBM 32-bit SDK for Linux V1.5。SLES9 SP3 附带了 IBM 32-bit SDK
for Linux V1.4.2,而 SLES10 SP2 附带了 32-bit IBM SDK V1.4.2 以及 IBM
32-bit 和 64-bit SDK for Linux
V1.5。应用程序开发人员必须注意这些差别,避免应用程序仅依赖于在 5.0
版本中可用的特性。

.so文件的相关注意事项

在Xcode 8中,苹果提供了Migration
Assistant,它可以完成大部分的迁移工作。当然,仍然有一部分工作是需要你手动完成的。

除了标准库,通过共享 ABI,Scala 3.0 和 2.13
工件可以共同存于类路径上并且可以无缝地互操作,这样可以逐步迁移并简化测试。

2.6 内核在 RHEL4 和 SLES9 中引入了以下性能改进,并且在 RHEL5 和 SLES10
版本中得到进一步改进:

SO(CPU)的兼容

每一个CPU架构对应一个ABI,一个cpu属于某一种架构,多核cpu需要属于相同架构才能一起工作,很多设备仅支持一种的CPU架构。

如果你要完美兼容所有类型的手机,理论上是要在的libs目录下放置各个架构平台的SO文件。

www.9778.com 3

七种不同类型的CPU架构

这样一写,虽然可以兼容所有机型,但你的项目体积也会变得非常庞大。是否一定需要带入这么多SO文件去兼容呢?答案是否定的。

对于CPU来说,不同的架构并不意味着一定互不兼容,根据目前Android共支持七种不同类型的CPU架构,其兼容特点可总结如下:

armeabi设备只兼容armeabi;
armeabi-v7a设备兼容armeabi-v7a、armeabi;
arm64-v8a设备兼容arm64-v8a、armeabi-v7a、armeabi;
X86设备兼容X86、armeabi;
X86_64设备兼容X86_64、X86、armeabi;
mips64设备兼容mips64、mips;
mips只兼容mips;

根据以上的兼容总结,我们还可以得到一些规律:

  • armeabi的SO文件基本上可以说是万金油,它能运行在除了mips和mips64的设备上,但在非armeabi设备上运行性能还是有所损耗;
  • 64位的CPU架构总能向下兼容其对应的32位指令集,如:x86_64兼容X86,arm64-v8a兼容armeabi-v7a,mips64兼容mips;

为了便于开发者们将代码迁移到 Swift 3,苹果在 Xcode 8 中增加了一个 Swift
版本,即 Swift 2.3,对 Swift
作了一个小小的升级。如果你是一个开发者,Swift 2.3 和 2.2
实际并无不同,但 Swift 2.3版本能够支持本次WWDC中提到的各种新的SDK 和
Xcode 特性。在 Xcode 8 推出 beta 版时,你可以用 Swift 2.3 来提交你的
app,而不用将代码迁移到 Swift 3。

主要目标是提供从 Scala 2 到 3
的平滑且增量的迁移路径,要实现此目的,Scala 2.13 和 3.0
将使用相同的标准库,并且它们的编译器后端将以相同的方式输出字节码。

不过,在 RHEL5 中的以下两方面进行重新编译能够改进应用程序的性能:

现有的常用ABI

应用程序二进制接口(Application Binary
Interface)定义了其所对应的CPU架构能够执行的二进制文件(特别是.so文件)的格式规范。在Android系统上,不同
Android 手机使用不同的 CPU,因此支持不同的指令集。CPU
与指令集的每种组合都有其自己的应用二进制界面(或 ABI)。 ABI
可以非常精确地定义应用的机器代码在运行时如何与系统交互。
您必须为应用要使用的每个 CPU 架构指定
ABI:armeabi,armeabi-v7a,x86,mips,arm64-v8a,mips64,x86_64【1】。

典型的 ABI 包含以下信息:

  • 机器代码应使用的 CPU 指令集。
  • 运行时内存存储和加载的字节顺序。
  • 可执行二进制文件(例如程序和共享库)的格式,以及它们支持的内容类型。
  • 用于解析内容与系统之间数据的各种约定。这些约定包括对齐限制,以及系统如何使用堆栈和在调用函数时注册。
  • 运行时可用于机器代码的函数符号列表 – 通常来自非常具体的库集。
  • 支持一个或多个指令集。

结尾

Scala 官方公布了 Scala 2 接下来的发展计划,开发团队表示工作将转向 Scala
3,而不是开发 Scala 2.14。

  • 对于包含大量处理器的系统,在 RHEL5 中重新编译 NUMA user-land API
    会提高性能(如果还没有在 RHEL4
    中进行编译的话)。尽管从总体上看应用程序都能够从内核级别 NUMA
    支持获得性能改进,但是重新编译这些 user-land API
    还可以获得进一步的性能改进。处理器密集型和内存访问频繁的应用程序将获得最大收益,因为
    NUMA 减少了处理器访问内存区域的时间。
  • 使用 RHEL5
    中的最新编辑器进行重新编译时,其他应用程序也可能获得性能改进。这些编译器添加了利用
    POWER6 优化的标志,如本文前面所述。

转载整合自:
关于Android的.so文件你所需要知道的
和Android SO
文件的兼容和适配
不论是否被发现,一切荣誉归属于大佬。

你会发现代码很难读懂。参数在哪里结束,返回值从哪里开始?在 Swift 3
中,正确的定义方法是[SE-0066]:

如果在从 2 到 3
的迁移期间,迫切需要在这些限制之外发展标准库,开发团队可能最终仍会选择发布
Scala 2.14 版本。

从 SLES9 迁移到 SLES10

现有的CPU架构类型

开发Android应用时,有时候Java层的编码不能满足实现需求,就需要到C/C++实现后生成SO文件,再用System.loadLibrary()加载进行调用,这里成为JNI层的实现。常见的场景如:加解密算法,音视频编解码等。在生成SO文件时,需要考虑适配市面上不同手机CPU架构,而生成支持不同平台的SO文件进行兼容。目前Android共支持七种不同类型的CPU架构,分别是:ARMv5,ARMv7
(从2010年起),x86 (从2011年起),MIPS
(从2012年起),ARMv8,MIPS64和x86_64 (从2014年起)

这是具体的例子[SE-0068]:

但是,这也意味着对标准库的二进制不兼容更改将不得不等到 Scala 3.x
系列中的稍后版本,届时将拥有补救二进制不兼容的工具。更具体地说,由于
Scala 2.13
在其系列之内保持向前和向后二进制兼容,因此无法添加或删除任何类或方法。

可以通过不同的方式生成 32 位和 64 位 Linux
二进制文件,这取决于开发平台:

参考文章

关于Android的.so文件你所需要知道的
Android SO
文件的兼容和适配
ABI
Management

ABI 稳定要求应用程序和库无论使用哪个版本的编译器编译,都能被 link
和能够彼此进行交互。这对于第三方库来说是个重要的进步,因为这样就可以不需要提供源码就可以封装出框架了,而现在新版本的
Swift 不但要这些第三方库修改代码,还要重新进行编译。

除了技术互操作性之外,开发团队还将关注于测试和改进工具,以确保顺利迁移。例如,原定于
2.14 版本中进行的迁移警告将在 2.13 中实施。

Red Hat 在 RHEL4 和 RHEL5 之间维护了一个稳定的
ABI,因此可以在这两个版本之间顺利地迁移应用程序。不过,为了确保二进制兼容性,Red
Hat 建议您将您的应用程序接口链接到它们所定义的核心库。核心库列表包括:

除了对已有 API 进行“旧瓶新装”这个最大的改变以外–有非常多的 Swift
社区正致力于此,也有对 Swift API 的一些功能上的增加。

长期以来,开发团队认为必须有 2.14 版本才能确保顺利过渡到
3,但是经过大量的研究和讨论,现在确信完全不需要
2.14。这样可以带来两方面的好处:

编写能够在多个 Linux
发行版之间移植的应用程序看起来是一个困难的任务,但只要遵循一些简单的实践就可以实现该目的。大部分发行版的最新版本通常包含相同级别的库和内核版本。大部分发行版还使用类似格式的配置和数据文件。

sequence(first:next:) 以及 sequence(state:next:)
是全局函数,返回一个无限序列。你传给它们一个初值或一个可变的状态,它们会在稍后调用闭包中的代码[SE-0094]:

www.9778.com 4

不仅 ABI 在 RHEL4 和 RHEL5 之间保持稳定,并且 RHEL5 中的许多其他 2.6
内核特性也与 RHEL4 兼容。这就允许 RHEL4 应用程序现成地利用 RHEL5
中包含的 Simultaneous Multi-threading (SMT) 和 Native Posix Thread
Library (NPTL)
等特性获得性能改进,而不需要重新编译它们的源代码。这些应用程序还可以利用
2.6 内核中的性能改进,如本文前面所述。

  

共享标准库消除了 Scala 2.13 和 3 之间的主要潜在差异,并有助于迁移。

SLES8 SP4 RHEL3 U4 SLES9 SP3 RHEL4 U8 SLES10 SP2 RHEL5 U3
kernel 2.4.21 2.4.21 2.6.5 2.6.9 2.6.16 2.6.18
glibc 2.2.5 2.3.2 2.3.3 2.3.4 2.4 2.5
SMT No No Yes Yes Yes Yes
NPTL No No Yes Yes Yes Yes
NUMA No No Yes Yes Yes Yes
JDK IBM 1.3.1 IBM 1.4.2¹ IBM 1.4.2 IBM 1.4.2 IBM 1.4.2, 5.0 IBM 1.4.2, 5.0
Apache 1.3.26 2.0.46 2.0.49 2.0.52 2.2.0 2.2.3
GCC 3.2 3.2.3 3.3.3 3.4.6 4.1.2 4.1.2

工具的改善

  • Scala 3
    将可以更快地投入生产环境。在完善编译器和升级相关工具方面,有许多工作要做,同时将帮助生态系统升级。

  • 无需为 2.14 重建 Scala
    库和工具生态系统,从而节省了维护人员的时间以准备 Scala 3。

其他 2.6 内核改进

  

(文/开源中国)    

例如,在包含 glibc 2.3.3 的 SLES9 系统上编译的二进制文件可以在包含 glibc
2.4 的 SLES10 系统上运行,因为 2.4 版本是向后兼容的。不过,在 SLES10
上编译的相同源代码将不能在 SLES9 系统上运行,因为它包含旧的
glibc。仅当您在当前的发行版上开发应用程序,并且想在不提供旧版本兼容库的旧发行版上运行该应用程序时,才会出现这种问题。

另一个和过去的 Swift 代码不同的地方是,在枚举中定义的 case
值现在使用小驼峰命名法。这是为了和属性名或者变量名保持一致[SE-0006]:

目前 Scala 3 已经向后兼容,它可以使用由 Scala 2.13
构建的库。为了实现向前兼容,Scala 3
编译器将提供一种机制来确保公共接口位于公共语言子集中,以便可以在 Scala
2.13 中使用它。这意味着作为库作者的开发者可以直接使用某些 Scala 3
内容,而无需从 Scala 2.13 升级。

  • 在 32 位 PowerPC 平台(比如运行 Linux 的 Apple Powerbook)上的本机
    GNU Compiler Collection (GCC) C 编辑器能够生成可以在本机 32
    位平台上,或在包含适当 32 位用户空间库的 64 位 Linux on POWER
    平台上执行的 32 位二进制文件。
  • IBM XL C/C++, Version 8.0 和针对 64 位 Linux on POWER 的 GCC C
    编译器能够生成 32 位和 64 为二进制可执行文件,这些文件可以在 32 位或
    64 位运行时环境中执行。
  • 还 存在可以同时在 32 位 PowerPC Linux 系统和 64 位 Linux on POWER
    系统上运行的跨系统编译器。这些跨系统编译器能够生成 32 位和 64
    位二进制文件。不管在什么地方构建二进制文件,32
    位的二进制文件都可以在 32 位 Linux 平台或 64 位 Linux
    平台上运行,而生成的 64 位二进制文件仅能在 64 位 Linux on POWER
    系统上运行。跨系统编译器的一个例子是 Crosstool(参考资料
    部分提供相关链接)。

  

共享的 ABI

使用 Linux 2.6.16
内核时,必须根据共享内存的分配方式进行一些更改。如果处理器正在查找存储在相邻的
cell board 上的内存中的数据,Linux 2.6.16
内核能够获取该信息并将其移动到本地内存中(运行速度更快),然后在本地内存中执行所需的操作,而不需重新启动该操作。

另外,Swift
正在持续改进:命名变得更规范,代码读起来更清晰,你可以用工具来迁移代码。如果你想进一步深入了解,请看WWDC
的会议视频。

  • 通用的打包和安装指南
  • 通用的共享库及其选择
  • 配置文件
  • 文件位置
  • 系统命令
  • 针对系统接口的 Application Binary Interfaces(应用程序和平台级别)

如果你当前正在编写类型内部的代码,还是要使用类型名来调用静态方法。为了使表述更加清晰,现在你可以通过
Self 来引用当前实例所属类型。S 为大写的 Self 表示引用当前实例的类型,而
s 为小写的 self 则引用当前实例自身。


自从 Swift 开源以来,社区成员已经提交了超过 100
个改进建议。其中大部分(70多个)提议经过讨论修改之后已经被接受。还有一些仍然在激烈的争论之后被拒绝了。但最终,所有提议都要经过核心团队的最终拍板。

在 Linux 2.6.15 内核中,NUMA
优化通过指定仅本地处理器能够访问内存,从而改进了跨大型系统(处理器核在
4-8 个以上)运行的工作负载的性能。如果处理器正在查找存储在相邻的 cell
board 上的内存中的数据,Linux 2.6.16
内核能够获取该信息并将其移动到本地内存中(运行速度更快),然后在本地内存中执行所需的操作,而不需重新启动该操作。

  

-qarch 和 -qtune 选项用于为各自的架构优化性能。例如,要优化 POWER6
的性能,使用 -qarch=pwr6 和 -qtune=pwr6。此外,还引入了 -qtune=balanced
选项。这个选项与 -qarch=pwr5(或 pwr5x)一起使用时,将生成可以在 POWER5
和 POWER6 系统上运行的二进制文件,但包含能够改进 POWER6
性能的调度改进。Version 9 还包含对 AltiVec Vector Multimedia Extensions
(VMX) 的支持,VMX 最初是在 IBM PowerPC 970 处理器上提供的,现在通过
-qaltivec 选项整合到 POWER6 产品系列。

//old way, Swift 2, followed by new way, Swift 3
UIInterfaceOrientationMask.Landscape
UIInterfaceOrientationMask.landscape
NSTextAlignment.Right
NSTextAlignment.right
SKBlendMode.Multiply
SKBlendMode.multiply

二进制兼容性考虑事项

 

二进制兼容性是指能够在特定处理器系列的多个环境中运行二进制文件的能力。这些环境可能是相同
Linux 发行版的不同版本,或者是完全不同的版本。例如,在基于 POWER6™
处理器并运行 SLES10 的系统上运行可以在基于 POWER5™ 处理器并运行 SLES10
的系统上编译和运行的二进制文件。另一个例子是,在基于 POWER6™
处理器并运行 SLES10 的系统上运行可以在基于 POWER5™ 处理器并运行 RHEL4
的系统上编译和运行的二进制文件。

下面是一些使用这些方法的代码片段:

  • 对源代码进行少量修改并根据基于 NPTL 的库进行重新编译,以获得 NPTL
    带来的性能改进。可以在 LinuxDevices.com 的文章 “Migrating
    applications to the 2.6 kernel and NPTL” 找到更多关于从 LinuxThreads
    模型迁移到基于 NPTL 模型的信息(参考资料 部分提供相关链接)。
  • 设 置 LD_ASSUME_KERNEL 环境变量,它为 SLES9 中的 LinuxThreads
    模型提供向后兼容性。通过设置这个环境变量,连接器将认为 2.4
    内核运行旧的 LinuxThreads 模型。Red Hat 开发人员 Ulrich Drepper
    详细解释了 LD_ASSUME_KERNEL(参考资料
    部分提供相关链接)。不过,由于 SLES10 中的 glibc
    发生了变化,基于旧的 LinuxThreads
    模型的语义的应用程序将不能正常工作,因为在 SLES 10 中旧的
    LinuxThreads 模型已经被新的 NPTL 取代。这还意味着 LD_ASSUME_KERNEL
    环境变量的值仅能被设置为大于 2.6.4 的值。最好根据更新的 NPTL —— SLES
    9 中的默认 NPTL —— 进行测试。

枚举中 case 值的大小写

参与 Linux Foundation 的 Linux Standard Base(LSB)项目的 Red Hat 和
Novell 都有一个共同的目标,即开发和推广一组开放标准,以增强 Linux
发行版之间的兼容性,以及支持应用程序以二进制文件的形式在遵循这些标准的系统中运行。此外,LSB
将帮助征集为 Linux 操作系统移植和编写产品的软件供应商。LSB
的关键组件是二进制接口规范,它告诉 Linux
应用程序开发人员构建和配置应用程序的标准方式。该规范特别列出了:

行内Sequences

中间件和应用程序兼容性

我建议你在 Playground 中测试本文讨论的新特性,还可以用你的某个项目来测试
Migration Assistant,以便你对这些改变有所了解。由于在 Xcode 8 beta
下一个版本及 Siwft 3 正式发布之前,你无法向 App Store 提交
App,那么我建议暂时先不要讲代码迁移到Swift 3。

以下小节详细介绍一些 LSB
规范,并且为编写可以跨不同发行版移植的应用程序提供一些指导原则。

func g(a: Int -> Int) -> Int -> Int  { ... } // old way, Swift 2
发行版 32 位 64 位
RHEL3 > RHEL4 向前兼容 向前兼容
RHEL4 < RHEL3 向后兼容 向后兼容
SLES9 > SLES8 向前兼容 NA
SLES8 < SLES9 NA NA
CustomStruct.staticMethod()

线程模式

第一个参数的 label

开发平台 编译器 生成的 Linux 二进制文件
32 位 Linux on PowerPC 本机 GCC C 编译器 32 位
64 位 Linux on POWER 本机 XL C/C++ 或 GCC C 编译器 32 位或 64 位
32 位 Linux on PowerPC 或
64 位 Linux on POWER
跨系统编译器,比如 crosstool 32 位或 64 位

计划中的特性

  • 64 位 Power Architecture 支持完整的 32 位 PowerPC 架构。
  • 64 位 Linux 内核能够处理 32 位系统调用。
  • 32 位运行时环境包含必要的 32 位库。
  • 64 位运行时环境包含必要的 32 位和 64 位库。

如果这个方法不使用介词也不使用
label,你应该在方法定义时,显式地在第一个参数名之前加一个下划线:

从 SLES9 迁移到 SLES10 也是比较顺利的。尽管在 SLES9 中引入了 NPTL
线程模型(不再使用旧的 LinuxThreads 模型),但 NPTL 是 SLES10
中唯一支持的线程模型,因为 Glibc 库不再支持 LinuxThreads。在 “线程模型”
小节描述了更改线程模式导致的问题,解决了从一个线程模式改用另一个线程模式出现的问题。尽管使用更少通用库的非线程应用程序能够更好地维护
SLES 版本之间的二进制兼容性,但必须执行回归测试以确保质量。

访问所属类型

对于 RHEL,在某些情况下重新编译源代码可能有利于将要在 SLES10
上运行的应用程序。例如,通过利用 SLES10
中的改进编辑器可以提升应用程序的性能。SMT 也是 SLES10
中的一个新特性,它能够提升包含大量线程的应用程序的性能。

func g(a: Int -> Int) -> Int -> Int  { ... } // old way, Swift 2

另一个例子是,尽管 Apache web
服务器是非中间件应用程序,但是许多应用程序都依赖它。Apache 的最新版本是
2.2,它附带了 RHEL5 和 SLES10,而 Apache 2.0 附带的是 RHEL4 和
SLES9。如果应用程序包含的特性仅在 Apache 2.2 中可用,那么它们可能与附带
RHEL4 和 SLES9 的 Apache 2.0 不兼容。

// old way, Swift 2
let ctx = UIGraphicsGetCurrentContext()
let rectangle = CGRect(x: 0, y: 0, width: 512, height: 512)
CGContextSetFillColorWithColor(ctx, UIColor.blueColor().CGColor)
CGContextSetStrokeColorWithColor(ctx, UIColor.whiteColor().CGColor)
CGContextSetLineWidth(ctx, 10)
CGContextAddRect(ctx, rectangle)
CGContextDrawPath(ctx, .FillStroke)
UIGraphicsEndImageContext()
// new way, Swift 3
if let ctx = UIGraphicsGetCurrentContext() {
    let rectangle = CGRect(x: 0, y: 0, width: 512, height: 512)
    ctx.setFillColor(UIColor.blue().cgColor)
    ctx.setStrokeColor(UIColor.white().cgColor)
    ctx.setLineWidth(10)
    ctx.addRect(rectangle)
    ctx.drawPath(using: .fillStroke)
    UIGraphicsEndImageContext()
}

可以在 developerWorks 文章 “How to use IBM XL C/C++ Advanced Edition
V8.0 for Linux on POWER: A guide for GCC users” 上找到更多关于在 Linux
on POWER 上使用 XL C/C++ 编辑器的信息。

 

2.6 内核和 POWER6
架构包含能够改进应用程序的性能的特性。性能的改进得益于不同的库、处理器特性和编译器更新。有一些性能改进不需要修改应用程序,而另一些性能改进需要重
新编译源代码。记住,重新编译以获得性能改进可能会损害二进制文件在某些环境中的兼容性。这个小节提供一些例子,它们展示能够改进应用程序性能的
2.6 内核新特性和 POWER6 架构。

开始

处理器兼容性

杂项

了解二进制兼容性以及它与运行在 Linux® on POWER™
上的不同操作环境之间的关系。考察 IBM 支持的两个 Linux on POWER
发行版,即 Red Hat Enterprise Linux (RHEL) 和 SUSE LINUX Enterprise
Server
(SLES),了解它们各自的各个版本之间的二进制兼容性。总体而言,通过在版本之间维护的稳定
Application Binary Interface (ABI) 可以实现从基于 2.6.9 内核的 RHEL4
顺利迁移到基于 2.6.18 内核的 RHEL5。该方法同样适用于从基于 2.6.5
内核的 SLES9 迁移到基于 2.6.16 内核的 SLES10。了解能够改善 Linux on
POWER
应用程序的性能的新技术,并遵循一些步骤确保未来的多个发行版之间的二进制兼容性。[“参考资料”
部分提供额外的参考内容 —— 编辑。]

现在,参数列表被括号包裹,然后才是返回类型。事情变得简单,同时函数类型更容易被识别出来。通过下面的比照,你会更清楚:

表 1. 受支持的特性以及 RHEL 和 SLES 发行版的代码级别

新的 GCD 和 Core Graphics

Linux on POWER 的二进制兼容性通过遵循 Application Binary Interface (ABI)
来实现。ABI
是一个接口,编译后的二进制文件通过它访问操作系统及其服务。当多个操作环境支持相同的
ABI 时,就可以在这些操作环境中运行相同的二进制文件。可以在 “64-bit
PowerPC ELF Application Binary Interface Supplement 1.7” 中找到关于
PowerPC® Executable 和 Linking Format (ELF) ABI 的 64
位补充的更多信息(参考资料 部分提供相关链接)。

func f(a: Int) { ... }
f(5)

表 3 显示了 32 位和 64 位应用程序在不同的 RHEL 和 SLES
版本上的向后和向前兼容性:

  • keyPath() 等同于 #selector() ,帮助你减少输入错误

  • 你可以在某些类型上调用
    pi,比如:Float.pi、CGFloat.pi。大部分时候编译器能够推断出类型:let
    circumference = 2 * .pi * radius
    [SE-0067]

  • NS 前缀从老的 Foundation 类型中移除,现在可以用 Calendar、Date来替代
    NSCalendar、NSDate 了

SLES8 基于 2.4 内核并保护 LinuxThreads 模型,当尝试运行包含 NPTL
线程模型的 SLES9
上的包含大量线程的应用程序时,它将出现问题。可以通过两种途径解决这个问题:

customArray.enumerate()
customArray.enumerated()
customArray.reverse()
customArray.reversed()
customArray.sort() // changed from .sortInPlace()
customArray.sorted()

核心库

总之,你现在只能保持源代码的版本兼容,而二进制版本的兼容当前仍然是不可能的。

表 2 显示了如何为不同的开发平台生成 32 位和 64 位 Linux 二进制文件:

Grand Central Dispatch
常用于长时间计算或者与服务器通讯。将任务放到不同的线程,你可以避免阻塞用户界面。libdispatch
库是用 C 语言编写的,提供了 C 风格的 API。这个 API 现在在 Swift
中被重新设计为[SE-0088]:

当今的许多应用程序都不是自含的,而是依赖于中间件。中间件是位于两个应用程序之间或位于应用程序和操作系统之间的软件。中间件的例子包括
IBM DB2® Universal Database for Linux、Java™ Development Kit (JDK) 和
IBM WebSphere®
应用程序。开发人员可以决定他们的应用程序支持的中间件版本,
但是中间件提供商决定他们的产品将运行在哪个 Linux 发行版上。可以在 IBM 的
Linux 软件 Web 站点上找到 IBM 的 Linux 中间件列表。(参考资料
部分提供相关链接)。除了中间件之外,应用程序还可能依赖于发行版附带的其他应用程序。其中的例子包括
Apache web 服务器、数据库系统(比如 mysql 和
postgresql)和解释语言(比如 perl 和 python)。

  

确保跨发行版之间的兼容性

已实现的 Swift Evolution 提议

  • 可以扩展到 64 位 SMP POWER6 处理器的可伸缩性。
  • 对内存密集型应用程序的大页支持,允许 16MB 的页大小,同时也提供传统的
    4KB 页大小。
  • 在 Red Hat Enterprise Linux 5 中引入 64KB 的页大小。
  • 虚拟内存子系统改进,包括在内存压力比较大的系统中提供的反向映射算法。
  • 块 I/O 和异步 I/O 改进。

省略不必要的单词

二进制兼容性概述

// old way, Swift 2, followed by new way, Swift 3
let blue = UIColor.blueColor()
let blue = UIColor.blue()
let min = numbers.minElement()
let min = numbers.min()
attributedString.appendAttributedString(anotherString)
attributedString.append(anotherString)
names.insert("Jane", atIndex: 0)
names.insert("Jane", at: 0)
UIDevice.currentDevice()
UIDevice.current()

从 RHEL4 迁移到 RHEL5

  

表 2. 生成 32 位和 64 位 Linux 二进制文件

升级到Swift
3时,你会发现基本上每个文件都需要改动!之所以这样,是因为所有的 Cocoa
API 名称都改变了。简而言之,API还是原来的 API,但这个 API 在 Objective-C
中是一种叫法,而在 Swift 中是另一种叫法。Swift
3的语法书写起来要更贴近于自然语言。


UpperCamelCase命名法现在只在类型名和协议名上使用。当你习惯这一切之后,Swift团队对于追求一致性的努力才没有白费。

尽管已经演示了 32 位和 64
位环境之间的兼容性,但这并不意味着官方发行版支持这种兼容性。Red Hat 在
RHEL3 和 RHEL4 之间向前或向后支持 32 位和 64 位兼容性,而当从 SLES8
迁移到 SLES9 时,SLES8 仅支持 32 位向前兼容性。

  

当重新编译应用程序以改善性能时,必须考虑可能损害二进制兼容性的风险。不过,在大部分情况下,将应用程序从
RHEL4 迁移到 RHEL5 时不需要额外的工作。

 

在文章 “Red Hat Enterprise Linux 4 Application Compatibility”
中讨论了核心库和其他兼容性问题(参考资料
部分提供相关链接)。尽管这个文档阐述的是 RHEL4
中的兼容性,但其中的概念和理念适用于 RHEL5
中的应用程序兼容性问题。使用核心库之外的其他库的应用程序仍然可以实现兼容性,但需要进一步执行回归测试。应用程序不保留二进制兼容性的情况包括,应用
程序静态地链接到其他库、依赖内核级别接口,或与 POSIX 标准或 64 位 POWER
ABI 定义冲突。

  

PowerPC 和 POWER 处理器兼容性

在许多编程语言中,许多方法可以共用一个方法名,但参数名不同。Swift
也不例外,现在,你可以重载方法,APIs
能够将直接将它们转换成合适的调用。下面是一个例子,展示了 index()
方法的两种重载形式:

编译器改进

  

现在有许多可用的 Linux 发行版。尽管 Red Hat 和 SUSE LINUX 是 IBM 支持的
Linux on POWER 解决方案供应商,但其他发行版(比如 Gentoo、Debian 和
Ubuntu)也逐渐变成流行的 Linux on POWER
解决方案。应用程序通常喜欢确保他们的应用程序能够运行在多个发行版上,以及运行在同一个发行版的不同版本上。理解与二进制兼容性相关的问题之后,就能够
实现这些目标。本文定义二进制兼容性、讨论维护兼容性的考虑事项并探讨不同版本之间的迁移,包括
Red Hat Enterprise Linux 的版本 4 和 5,SUSE LINUX Enterprise Server
的版本 9 和
10。此外,还提供确保应用程序能够跨多个发行版实现兼容性的实践。

var ages = [21, 10, 2] // 变量,不是常量,这样你才能修改它
ages.sort() // 修改值,现在值变成了 [2, 10, 21]
for (index, age) in ages.enumerated() { // "-ed" 是名词,表示会返回一个 ages 拷贝
print("(index). (age)") // 打印:1. 2 n 2. 10 n 3. 21
}

当在不同的操作环境中运行应用程序时,另一个考虑事项是低级内核依赖项。应用程序不兼容的一个例子就是将信息从
/proc 文件系统移动到 sysfs
文件系统,如果应用程序在这些文件系统之一中用硬编码值编写的话。/proc
文件系统最初是一个常驻文件系统,它允许用户空间访问包含信息的内核数据结构,比如系统和设备状态信息。这些信息将从
/proc 文件系统移动到 sysfs 文件系统。/proc
文件系统仍然存在,但它仅包含进程信息。

类似于你所用过 Cocoapods 或 Carthage 这些包管理器,Swift
包管理器会下载依赖项并编译它们,把它们 link 成库或可执行文件。已经有
1000 个库支持 Swift 包管理器,并且在未来几个月中,还会有更多的库支持它。

SMT

www.9778.com 5

尽管根据 ABI
和处理器系列定义了二进制兼容性,但是在确定应用程序是否能够跨多个环境运行时,还有一些其他兼容性事项需要考虑。其中的例子包括线程模型、低级内核依赖
项、中间件和核心库。这个小节讨论这些考虑事项并描述 Linux on POWER
如何处理它们。

返回值的方法或者修改值的方法

¹您可以从 IBM 站点下载 IBM Developer Kit for Linux, Java™ Technology
Edition。(参考资料 部分提供相关链接)。

泛型增强包括递归协议约束和能够将一个受约束的扩展符合新协议(例如,一个用于存放
Equatable 对象的数组也应当遵守 Equatable
协议)。在这些特性尚未实现之前,Swift 不能被视作 ABI 稳定的。

例如,如果您仔细查看 RHEL 和 SLES 发行版中包含的 glibc 库,就会发现
RHEL4 包含的是版本 2.3.4 而 SLES9 包含的是
2.3.3。小的修改通常是添加了修复包,而不是增加新的特性。RHEL4、RHEL5、SLES9
和 SLES10
都包含相似的线程模型,因此链接到通用库的任何应用程序应该都能够在这 3
个操作环境中运行。您还可以在其他发行版(比如 Gentoo 和
Debian)中找到通用库。

  • 改善了字符串的 Hash 算法,导致在将字符串存入字典后,性能有 3
    倍的提升

  • 将对象从堆移到栈中存放,导致性能有 24 倍的提升(某些情况下)

  • 编译器可以一次缓存多个文件(在整个模块被优化过的情况下)

  • 优化了代码的大小,导致 Swift
    代码的编译尺寸更小。以苹果的 Demobots 为例,编译尺寸缩减了原大小的
    77%。

由于 POWER5 和 POWER6 架构能够扩展到 64 位处理器,大部分应用程序都得益于
2.6 内核级别的 NUMA 支持。设法提高性能的应用程序可以使用 user-land NUMA
API。RHEL4 附带了 user-land NUMA API,以及更多关于如何在 NUMA Group
主页使用这些 API 的信息(参考资料 部分提供相关链接)。

一提到遗留下来的“元老级”API,GCG 和 Core Graphics
更需要被重新“装扮一新”。


  

核心库的主要修改也可能导致二进制兼容性问题。向后兼容性是在库之间的主要修改中维护的。这允许应用程序根据特定库的旧版本进行编译,以运行该库的新版本。如果库的两个版本之间出现主要修改,那么根据特定库的最新版本进行编译的应用程序将不能在该库的旧版本上运行。

API中新增功能

表 3. 在 RHEL 和 SLES 发行版中的 32 位和 64 位兼容性

此外,如果 ABI 稳定就可以移除包含在二进制文件中的 Swift
标准库,因为就目前来说 iOS 和 macOS APP都是用 Xcode
创建的。目前的二进制文件中包含有 2 MB
左右的文件大小是为了确保能够兼容未来的操作系统。


本文中,我将重点介绍 Swift 3
中的重大改变,以及这些改变对你的代码的深刻影响。让我们开始吧!


struct CustomStruct {
  static func staticMethod() { ... }
  func instanceMethod() {
    Self.staticMethod() // in the body of the type
  }
}
let customStruct = CustomStruct()
customStruct.Self.staticMethod() // on an instance of the type

从 glibc 2.3 发布开始,Linux 中的线程模式就改变了,并且 Linux 内核也从
2.4 版本升级到 2.6 版本。在 glibc 2.2 和内核 2.4 中使用的传统
LinuxThreads 模型已被 Native Posix Thread Library (NPTL) 取代。NPTL
是从头构建的,为包含大量线程的应用程序提供出色的性能。可以在 Red Hat
文章 “The Native POSIX Thread Library for Linux” 找到更多关于 NPTL
规范的详细信息(参考资料 部分提供相关链接)。

for view in sequence(first: someView, next: { 0.superview }) {
// someView, someView.superview, someView.superview.superview, ...
}
  • libc、libgcc、libstdc++、libdl、libm、libutil、libcrypt、libz、libpthread
    和 libncurses
  • libX11、libXext、libXt、libICE、libSM 和 libGL
  • libgtk、libgdk、libgdk_pixmap、libpango、libatk、libglib、libgmodule、libgthread、libgnomeprint、libgnomeprintui、libgconf
    和 libglade

类似的情况还有 Core Graphics。Core Graphics 是用 C
编写的,曾经以来一直只能以”丑陋”的函数方式调用。这是它的新的用法[SE-0044]:

一般而言,大部分非线程应用程序都不会遇到 SLES9 和 SLES10
之间的二进制兼容性问题。不过,在对库和内核版本进行了主要修改之后,最好重新编译源代码,以让应用程序获得最佳的性能。

可以肯定的是,2016年末 Swift 3
的正式发布必将令人期待。我们将持续跟进所有改变,请继续关注我们的教程、新书预告和视频,我们将开始使用这些令人兴奋的改进。

POWER 处理器兼容性

Swift
3将于今年下半年推出,为Swift开发者们带来了很多核心代码的改变。如果你没有关注过
Swift Evolution 项目,你可能会好奇Swift
3中有什么改变,它会对你的代码带来什么影响,以及何时可以将代码移植到Swift
3。本文就将为你答疑解惑!

图 1. 确定应用程序的二进制兼容性
www.9778.com 6

 

当迁移到基于 2.6 的 Linux 内核时,Simultaneous Multi-threading (SMT)
还可以提供另一项性能收益。SMT 在 POWER6
上得到支持,并且大大改进了多线程应用程序的性能。POWER6
处理器有两个能够在每个处理器周期发出多条指令的硬件指令线程,从而改善了性能。不过,SMT
可能损害线程不是很多的应用程序的性能。可以在 Linux 内核启动时向其传递
smt-enabled=off 禁用 SMT。

  

优化性能

核心团队和广大社区之间的合作是卓有成效的。事实上,Swift 在 Github
上获得了 30,000
多颗星。每周都会有新的提议提交,周周如此。甚至苹果的工程师也会在 Github
上提交他们的提议。

表 1 显示了软件级别,以及本文将要详细讨论的 RHEL4、RHEL5、SLES9 和
SLES10 中受支持的特性:

在下一节中,你会看到一些类似 [SE-0001]
这样的标注。这是已经接受的提议编号,并且将在最终版的 Swift 3.0
中进行实现。每项提议都会标出,以便你查看每项改变的具体细节。


还可以用 prefix
操作符来为序列加一个限制[SE-0045]:

使用图 1 中显示的流程图确定应用程序在 RHEL 或 SLES
上是否实现二进制兼容。

但是,当你用函数类型作为参数时,你可能会写出这样的代码:

NUMA

  

低级内核依赖项

注意,有些方法使用介词”of”、”to”、”with”、”in”作为外部参数名。这是为了增加代码的可读性。

处理器兼容性是与 Linux on POWER
二进制兼容性密切相关的主题。这个小节讨论在不同的 64 位 POWER
处理器之间的兼容性,以及 32 位 PowerPC 处理器和 64 位 POWER
处理器之间的兼容性。

目前,Swift 3 预览版仅在 Xcode 8 beta版中可用。在未来几个月中,Swift 3
仍然在不断改变中,它还会发生一些变化。在 2016 年末,Xcode GM
发布时,Swift 3
的新特性才会稳定。所以各位开发者要沉住气,直到那个时候才可以向 App Store
提交用 Swift 3 编写的 App。

存储 Universal Serial Bus (USB) 设备列表是将系统信息从 /proc
文件系统移动到 sysfs 文件系统的一个例子。在系统中最初基于内核 2.4
编写的应用程序将在 /proc/bus/usb/devices
目录下找到该设备列表。在迁移到使用 2.6 内核的 sysfs
文件系统之后,该信息被移动到 /sys/bus/usb/devices
目录。这一信息移动将可能导致应用程序不能正常工作。尽管这种情况并不常见,但您应该注意内核级别的这类潜在问题。

在函数或方法中的第一个参数现在必须有一个 label
,除非你显式地声明不要。以前,我们调用一个函数或方法时,可以忽略第一个参数的
label[SE-0046]:

您可以考虑重新编译以利用 Linux on POWER
的最新编辑器的新特性带来的性能优势。现在,高性能编译器 IBM XL C/C++
Version 8 可以在基础级别的 RHEL4、SLES9 和 SLES10 上使用。IBM XL C/C++
Version 9 可以在 RHEL5 及其更新、SLES10 SP1 和 SP2 上使用。Version 9
添加了针对基于 POWER6 处理器的系统的性能改进。

Swift
只是一门语言,大部分时候你都无法离开书写它的开发环境–对于苹果开发者来说,也就是
Xcode!工具上的改变影响着每天编写代码的方式。

GNU Compiler Collection 包含针对多种不同语言的编译器。版本 3.3 到 4.1
得到了改进,包括对其 C 编译器 gcc 的特定于 POWER6 的优化。-mcpu=power6
和 -mtune=power6 标志现在得到支持,从而导致出现针对 POWER6
架构的注册表使用和指令调度参数。此外,还包含针对 IBM PowerPC 970 和 IBM
POWER6 处理器的 VMX
向量扩展,它们能够提升向量化代码的性能。尽管这些优化选项在各自的架构上改善了性能,但它们可能损害应用程序在其他平台上的二进制兼容性。

// old way, Swift 2, followed by new way, Swift 3
"RW".writeToFile("filename", atomically: true, encoding: NSUTF8StringEncoding)
"RW".write(toFile: "filename", atomically: true, encoding: NSUTF8StringEncoding)
SKAction.rotateByAngle(CGFloat(M_PI_2), duration: 10)
SKAction.rotate(byAngle: CGFloat(M_PI_2), duration: 10)
UIFont.preferredFontForTextStyle(UIFontTextStyleSubheadline)
UIFont.preferredFont(forTextStyle: UIFontTextStyleSubheadline)
override func numberOfSectionsInTableView(tableView: UITableView) -> Int
override func numberOfSections(in tableView: UITableView) -> Int
func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView?
func viewForZooming(in scrollView: UIScrollView) -> UIView?
NSTimer.scheduledTimerWithTimeInterval(0.35, target: self, selector: #selector(reset), userInfo: nil, repeats: true)
NSTimer.scheduledTimer(timeInterval: 0.35, target: self, selector: #selector(reset), userInfo: nil, repeats: true)

Non-uniform Memory Access (NUMA) 是针对 Linux on POWER 在 2.6
内核中引入的,这个特性在 RHEL5 和 SLES10
的最新版本中得到进一步优化。NUMA
解决了系统中的某些处理器因为总线位置不同到达特定内存区域的时间要比其他处理器长的问题。NUMA
通过在每个总线使用更多内存总线和更少处理器来减少系统共享内存总线的争用。尽管这在包含少量处理器的系统中作用不明显,但它能够在系统包含大量处理器时
改善性能。

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { ... }
override func didMoveToView(_ view: SKView) { ... }

许多 Linux 发行版都包含相同的 ABI
和通用的核心库。不过,每个发行版对核心库的定义都有些不同,因此在声称您的应用程序受特定发行版支持之前,通常需要执行回归测试。

在将 Objective-C 库转换成本地 Swift 语言方面,API
变得更智能了[SE-0005]:

这也说明,二进制稳定的目标还没有达到。本文最后将讨论这将导致的影响。

开源后的 Swift 实际上包含了 Swift
语言本身、核心库和包管理器。这三者一起构成了我们所见到的 Swift。Swift
包管理器定义了一个简单的目录结构,其中包括了你所共享和导入到项目中的
Swift 代码。

你可以立即将代码升级到 2.3 或者 3.0。如果你需要将代码又转回来,你可以用
Xcode 的 Edit > Convert > To Current Swift Syntax…
菜单。编译器会和 Migrateion Assistant
一样智能。如果你在调用方法时,偶然使用了老的 API,编译器会显示一个
Fixt-It 选项,让你使用正确的新 API。幸好 Swift 3
在最终发布时,才会停止改变源代码。因此,你可以将你的 Swift
代码保存为不同的版本。但是 Swift
核心团队不能保证这一点以后不会改变,如果在某个时候不在保证源码上的兼容,他们会提供一个较长的过渡期。这意味着源码是稳定的,这样能鼓励更多的保守的公司去使用它。

 

  

// old way, Swift 2, followed by new way, Swift 3
let blue = UIColor.blueColor()
let blue = UIColor.blue()
let min = numbers.minElement()
let min = numbers.min()
attributedString.appendAttributedString(anotherString)
attributedString.append(anotherString)
names.insert("Jane", atIndex: 0)
names.insert("Jane", at: 0)
UIDevice.currentDevice()
UIDevice.current()

Swift 包管理器

Xcode 也会更加智能地理解 Swift 代码:

我们以一个开发者每天都会在 Swift 中用到的例子开始。

let names = ["Anna", "Barbara"]
if let annaIndex = names.index(of: "Anna") {
print("Barbara's position: (names.index(after: annaIndex))")
}
for x in sequence(first: 0.1, next: { 0 * 2 }).prefix(while: { 0 < 4 }) {
// 0.1, 0.2, 0.4, 0.8, 1.6, 3.2
}

标准库中对方法名中使用动词和名词的规定也更加统一。你应当根据这个方法会导致什么后果或者要采取一些动作来进行方法命名。首要原则是如果这个方法名中包含”ed”或”ing”后缀,则表明这是一个名词。方法名为名词的方法有返回值。如果不包含这些后缀,则很可能这是一个动词。以动词命名的方法会对某块引用的内存进行一些操作。即所谓的”修改某个值”。下面是几个符合名词/动词命名规则的方法[SE-0006]:

当你定义一个静态属性或方法时,你直接通过类或类型来调用它们:

本文转自:

  

  

前面说过,Swift 3
尽量避免不兼容的改变,从而使你的代码能够从一个版本与下一个版本兼容。如果这是真的,那么在这次发布中应该还有一些更远大的目标未能达到,即泛型增强(generic
additions)和 ABI(程序二进制接口)稳定。

在早期的苹果标准库中,方法名中会包含一个单词,用于表明方法的返回值。因为
Swift
编译支持类型推断,这种做法其实并不必要。核心团队尽可能过滤一切”噪音”,因此将这些重复的单词都删除了,只留下方法名中最重要的部分。

升级到 Swift 3

函数类型

API 的改变

// old way, Swift 2
Int -> Float
String -> Int
T -> U
Int -> Float -> String
// new way, Swift 3
(Int) -> Float
(String) -> Int
(T) -> U
(Int) -> (Float) -> String

  

  • 过去,当你在一个 API 方法比如 sort()
    上右击并跳转到定义时,你会看到一个不太容易理解的头文件。现在,在
    Xcode 8 中,你会看到 sort() 方法实际上是 Array 类的扩展。

  • Swift
    Snapshots就如今晚发布的
    Swift Evolution 所说。在完全合并到 Xcode 之前,Snapshots
    提供了一个使用新语法的机会。Xcode 8 能够在 playgournd 中加载和运行
    Swift Snapshots。

原文:What’s New in Swift
3? ,作者:Ben
Morrow,译者:kmyhy

Swift 3 修正了编译器和 IDE 中的
Bug,还改善了报告错误和信息的精确性。就像你所期望的,每个版本的发布都会让
Swift 和编译器的运行变得更快:

Swift
仍然在不断演进,因为社区的目标是最佳实践。虽然它还很年轻,但它同时也面临着无比巨大的机遇和美好未来。Swift
现在已经能够在 Linux
上运行了,在未来几年,你还会看见它在更多的服务器和设备上运行。从头设计一门语言必然会破坏
ABI
稳定性,一旦等它稳定后这种破坏就变得小多了。这(开源)是唯一能够让这门语言变得更好的机会,否则我们必将后悔莫及。

方法名是同一个,但参数名不同,这将让人更容易记忆。

  

Swift 正在扩大它的影响力。苹果正在身体力行。苹果的团队们正在 Music
app、Console、Sierra画中画、Xcode 文档查看器、新的 iPad 版的Swift
Playground app 中使用 Swift。

函数在声明和调用时,都需要用括号将参数括住: