对苹果“五仁”编程语言Swift的简单分析

发布于:2014-07-02 13:41阅读数:

苹果在WWDC上发布的新编程语言Swift。从语言的特性上大家发现了好多语言的影子,这样的情况可以说是集大成,也可以说是“五仁”。每个人看问题的角度都不同,下面从个人的角度来看看这门

本文转自Proteas的博客

 

苹果在WWDC上发布的新编程语言Swift。从语言的特性上大家发现了好多语言的影子,这样的情况可以说是集大成,也可以说是“五仁”。每个人看问题的角度都不同,下面从个人的角度来看看这门语言涉及到的工具链及其对越狱开发的影响。

 

由于刚刚发布,针对相关工具的介绍几乎没有,那我们就从Xcode中寻找。在shell中执行:

  1. find /Applications/Xcode6-Beta.app/Contents/ -name "*swift*" 

 

可以找到Swift相关的文件,简单过滤后,如下的文件比较重要: 

  1. /Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift 
  2. /Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift-demangle 
  3. /Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift-ide-test 
  4. /Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift-stdlib-tool 
  5. /Applications/Xcode6-Beta.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/repl_swift 
  6. /Applications/Xcode6-Beta.app/Contents//Developer/Toolchains/XcodeDefault.xctoolchain/usr/share/man/man1/swift.1 

 

从找到的文件中我们可以看到包含 man 手册文件,我们首先看看手册的内容:

  1. swift(1)                                   Swift Documentation                                  swift(1) 
  2.  
  3. NAME 
  4.        swift - <strong>the amazingly new programming language</strong> 
  5.  
  6. SYNOPSIS 
  7.        swift [-emit-object|-emit-assembly|-emit-library|-i] 
  8.          [-help] 
  9.          -o output-file 
  10.          input-filenames 
  11.  
  12.        The full list of supported options is available via "swift -help"
  13.  
  14. DESCRIPTION 
  15.        Swift is a new, high performance systems programming language.  It has a clean and modern syntax, 
  16.        and offers seamless access to existing C and Objective-C code and frameworks, and is memory safe 
  17.        (by default). 
  18.  
  19.        Although inspired by Objective-C and many other languages, Swift is not itself a C-derived 
  20.        language. As a complete and independent language, Swift packages core features like flow control, 
  21.        data structures, and functions, with high-level constructs like objects, protocols, closures, and 
  22.        generics.  Swift embraces modules, eliminating the need for headers and the code duplication they 
  23.        entail. 
  24.  
  25.                                                2014-05-17                                       swift(1) 

 

从手册中可以得到的信息也非常有限,但是看到参数:-help,我们看看帮助会输出什么:

  1. OVERVIEW: Swift compiler 
  2.  
  3. USAGE: swift [options] <inputs> 
  4.  
  5. MODES: 
  6.   -dump-ast        Parse and type-check input file(s) and dump AST(s) 
  7.   -dump-parse      Parse input file(s) and dump AST(s) 
  8.   -emit-assembly   Emit assembly file(s) (-S) 
  9.   -emit-bc         Emit LLVM BC file(s) 
  10.   -emit-executable Emit a linked executable 
  11.   -emit-ir         Emit LLVM IR file(s) 
  12.   -emit-library    Emit a linked library 
  13.   -emit-object     Emit object file(s) (-c) 
  14.   -emit-silgen     Emit raw SIL file(s) 
  15.   -emit-sil        Emit canonical SIL file(s) 
  16.   -integrated-repl Integrated REPL mode 
  17.   -i               Immediate mode 
  18.   -lldb-repl       LLDB-enhanced REPL mode 
  19.   -parse           Parse input file(s) 
  20.   -print-ast       Parse and type-check input file(s) and pretty print AST(s) 
  21.   -repl            REPL mode 
  22.  
  23. OPTIONS: 
  24.   -application-extension  Restrict code to those available for App Extensions 
  25.   -arch <arch>            Compile for architecture <arch> 
  26.   -assert-config <value>  Specify the assert_configuration replacement. Possible values are Debug, Release, Replacement. 
  27.   -D <value>              Specifies one or more build configuration options 
  28.   -emit-dependencies      Emit Make-compatible dependencies files 
  29.   -emit-module-path <path> 
  30.                           Emit an importable module to <path> 
  31.   -emit-module            Emit an importable module 
  32.   -emit-objc-header-path <path> 
  33.                           Emit an Objective-C header file to <path> 
  34.   -emit-objc-header       Emit an Objective-C header file 
  35.   -framework <value>      Specifies a framework which should be linked against 
  36.   -F <value>              Add directory to framework search path 
  37.   -g                      Emit debug info 
  38.   -help                   Display available options 
  39.   -import-underlying-module 
  40.                           Implicitly imports the Objective-C half of a module 
  41.   -I <value>              Add directory to the import search path 
  42.   -j <n>                  Number of commands to execute in parallel 
  43.   -L <value>              Add directory to library link search path 
  44.   -l<value>               Specifies a library which should be linked against 
  45.   -module-cache-path <value> 
  46.                           Specifies the Clang module cache path 
  47.   -module-link-name <value> 
  48.                           Library to link against when using this module 
  49.   -module-name <value>    Name of the module to build 
  50.   -nostdimport            Don't search the standard library import path for modules 
  51.   -output-file-map <path> A file which specifies the location of outputs 
  52.   -o <file>               Write output to <file> 
  53.   -parse-as-library       Parse the input file(s) as libraries, not scripts 
  54.   -parse-sil              Parse the input file as SIL code, not Swift source 
  55.   -save-temps             Save intermediate compilation results 
  56.   -sdk <sdk>              Compile against <sdk> 
  57.   -serialize-diagnostics  Serialize diagnostics in a binary format 
  58.   -target-cpu <value>     Generate code for a particular CPU variant 
  59.   -target-feature [+-]<feature-name> 
  60.                           Generate code with a particular CPU feature enabled or disabled 
  61.   -target <value>         Generate code for the given target 
  62.   -version                Print version information and exit 
  63.   -v                      Show commands to run and use verbose output 
  64.   -Xcc <arg>              Pass <arg> to the C/C++/Objective-C compiler 
  65.   -Xfrontend <arg>        Pass <arg> to the Swift frontend 
  66.   -Xlinker <value>        Specifies an option which should be passed to the linker 
  67.   -Xllvm <arg>            Pass <arg> to LLVM. 

 

这么多参数到底怎么用呢?!我们一起来看看 Xcode 是怎么使用的。

 

打开Xcode6新建一个空工程,取名“FuckSwift”: 

 

将工程的Deployment Target改成 5.0,然后编译,并在设备上运行。我手上的设备是iPad2-iOS 7.0.4,可以正常运行。为什么可以正常运行?Swift相关的运行时库怎么处理?我们打开编译好的app目录:

 

可以看到比以前的程序多了一个目录 Frameworks,内容如下:

 

因此,在iOS 8之下的设备上,程序打包的时候带上了必要的运行库。对于iOS8,目前还没法解开 dyld cache 也就无法知道设备上是否带了这些库,不过应该会带。

 

接上文,我们建立测试工程的目的是为了看看 Xcode 如何使用 Swift 编译工具,xcoce编译时的相关参数如下: 

  1. /Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift  
  2. -target armv7-apple-ios5.0  
  3. -module-name FuckSwift  
  4. -O0  
  5. -sdk /Applications/Xcode6-Beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.0.sdk  
  6. -g  
  7. -module-cache-path /Users/proteas/Library/Developer/Xcode/DerivedData/ModuleCache  
  8. -I /Users/proteas/Library/Developer/Xcode/DerivedData/FuckSwift-czflmbyelvdrnvaxblvpkcrhfbie/Build/Products/Debug-iphoneos  
  9. -F /Users/proteas/Library/Developer/Xcode/DerivedData/FuckSwift-czflmbyelvdrnvaxblvpkcrhfbie/Build/Products/Debug-iphoneos  
  10. -parse-as-library  
  11. -c  
  12. -j8  
  13. /Users/proteas/Desktop/FuckSwift/FuckSwift/AppDelegate.swift  
  14. -output-file-map /Users/proteas/Library/Developer/Xcode/DerivedData/FuckSwift-czflmbyelvdrnvaxblvpkcrhfbie/Build/Intermediates/FuckSwift.build/Debug-iphoneos/FuckSwift.build/Objects-normal/armv7/FuckSwift-OutputFileMap.json  
  15. -serialize-diagnostics  
  16. -emit-dependencies  
  17. -emit-module  
  18. -emit-module-path /Users/proteas/Library/Developer/Xcode/DerivedData/FuckSwift-czflmbyelvdrnvaxblvpkcrhfbie/Build/Intermediates/FuckSwift.build/Debug-iphoneos/FuckSwift.build/Objects-normal/armv7/FuckSwift.swiftmodule  
  19. -Xcc  
  20. -iquote  
  21. -Xcc /Users/proteas/Library/Developer/Xcode/DerivedData/FuckSwift-czflmbyelvdrnvaxblvpkcrhfbie/Build/Intermediates/FuckSwift.build/Debug-iphoneos/FuckSwift.build/FuckSwift-generated-files.hmap  
  22. -Xcc -I/Users/proteas/Library/Developer/Xcode/DerivedData/FuckSwift-czflmbyelvdrnvaxblvpkcrhfbie/Build/Intermediates/FuckSwift.build/Debug-iphoneos/FuckSwift.build/FuckSwift-own-target-headers.hmap  
  23. -Xcc -I/Users/proteas/Library/Developer/Xcode/DerivedData/FuckSwift-czflmbyelvdrnvaxblvpkcrhfbie/Build/Intermediates/FuckSwift.build/Debug-iphoneos/FuckSwift.build/FuckSwift-all-target-headers.hmap  
  24. -Xcc  
  25. -iquote  
  26. -Xcc /Users/proteas/Library/Developer/Xcode/DerivedData/FuckSwift-czflmbyelvdrnvaxblvpkcrhfbie/Build/Intermediates/FuckSwift.build/Debug-iphoneos/FuckSwift.build/FuckSwift-project-headers.hmap -Xcc -I/Users/proteas/Library/Developer/Xcode/DerivedData/FuckSwift-czflmbyelvdrnvaxblvpkcrhfbie/Build/Products/Debug-iphoneos/include  
  27. -Xcc  
  28. -I/Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include  
  29. -Xcc -I/Users/proteas/Library/Developer/Xcode/DerivedData/FuckSwift-czflmbyelvdrnvaxblvpkcrhfbie/Build/Intermediates/FuckSwift.build/Debug-iphoneos/FuckSwift.build/DerivedSources/armv7  
  30. -Xcc -I/Users/proteas/Library/Developer/Xcode/DerivedData/FuckSwift-czflmbyelvdrnvaxblvpkcrhfbie/Build/Intermediates/FuckSwift.build/Debug-iphoneos/FuckSwift.build/DerivedSources  
  31. -Xcc  
  32. -DDEBUG=1  
  33. -emit-objc-header  
  34. -emit-objc-header-path /Users/proteas/Library/Developer/Xcode/DerivedData/FuckSwift-czflmbyelvdrnvaxblvpkcrhfbie/Build/Intermediates/FuckSwift.build/Debug-iphoneos/FuckSwift.build/Objects-normal/armv7/FuckSwift-Swift.h 

 

参数还是太多,继续精简,把去掉绝对路径:

  1. swift   -target armv7-apple-ios5.0 
  2.         -module-name FuckSwift 
  3.         -O0 
  4.         -sdk iPhoneOS8.0.sdk 
  5.         -g 
  6.         -module-cache-path ModuleCache 
  7.         -I Debug-iphoneos  
  8.         -F Debug-iphoneos  
  9.         -parse-as-library  
  10.         -c  
  11.         -j8  
  12.         AppDelegate.swift  
  13.         -output-file-map FuckSwift-OutputFileMap.json  
  14.         -serialize-diagnostics  
  15.         -emit-dependencies  
  16.         -emit-module  
  17.         -emit-module-path FuckSwift.swiftmodule  
  18.         -Xcc -iquote  
  19.         -Xcc FuckSwift-generated-files.hmap  
  20.         -Xcc -IFuckSwift-own-target-headers.hmap  
  21.         -Xcc -IFuckSwift-all-target-headers.hmap  
  22.         -Xcc -iquote  
  23.         -Xcc FuckSwift-project-headers.hmap  
  24.         -Xcc -Iinclude  
  25.         -Xcc -I/usr/include  
  26.         -Xcc -Iarmv7  
  27.         -Xcc -IDerivedSources  
  28.         -Xcc -DDEBUG=1  
  29.         <strong>-emit-objc-header  
  30.         -emit-objc-header-path FuckSwift-Swift.h</strong> 

 

这样就相对清晰了。这里面的参数大家可以对照上述的帮助查看,这里我们一起看两点:

1、Xcc <arg>:Pass <arg> to the C/C++/Objective-C compiler,这里我们可以得到:swift代码很可能最终被转变成C/C++/Objective-C代码进行静态编译。

2、会生成FuckSwift-Swift.h头文件,对比下这个文件与Swift文件。

  1. @UIApplicationMain 
  2. class AppDelegate: UIResponder, UIApplicationDelegate { 
  3.     var window: UIWindow? 
  4.     func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool { 
  5.         self.window = UIWindow(frame: UIScreen.mainScreen().bounds) 
  6.         self.window!.backgroundColor = UIColor.whiteColor() 
  7.         self.window!.makeKeyAndVisible() 
  8.         return true 
  9.     } 
  10.     func applicationWillResignActive(application: UIApplication) { 
  11.     } 
  12.     func applicationDidEnterBackground(application: UIApplication) { 
  13.     } 
  14.     func applicationWillEnterForeground(application: UIApplication) { 
  15.     } 
  16.     func applicationDidBecomeActive(application: UIApplication) { 
  17.     } 
  18.     func applicationWillTerminate(application: UIApplication) { 
  19.     } 

 

  1. SWIFT_CLASS("_TtC9FuckSwift11AppDelegate"
  2. @interface AppDelegate : UIResponder <UIApplicationDelegate> 
  3. @property (nonatomic) UIWindow * window; 
  4. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions; 
  5. - (void)applicationWillResignActive:(UIApplication *)application; 
  6. - (void)applicationDidEnterBackground:(UIApplication *)application; 
  7. - (void)applicationWillEnterForeground:(UIApplication *)application; 
  8. - (void)applicationDidBecomeActive:(UIApplication *)application; 
  9. - (void)applicationWillTerminate:(UIApplication *)application; 
  10. - (instancetype)init OBJC_DESIGNATED_INITIALIZER; 
  11. @end 

可以看到Swift程序是被转换了的,但是是不是转换成了Objective-C程序呢?还需要进一步分析。

 

打开IDA,加载测试程序的MachO: 

我们重点看下函数窗口: 

从函数名上我们可以得到如下结论:

1、可以看到函数名被“改编”了;

2、Swift代码并不是被简单得编译成了ObjC代码;

3、Swift代码最终被编译成了纯C代码,相对于ObjC来说省去了运行时查表进行函数调用的开销,执行效率应该比ObjC要高;

4、从文档上看Swfit相对于ObjC来说是更加动态的语言,开发效率也应该比ObjC高;

5、对于越狱开发来说,我们只要像Hook C函数那样来Hook Swift 函数就可以了,因此MobileSubstrate还是可以工作的;

6、生成的代码还是要遵循 ARM 的ABI标准。

 

就像C++的名称改编一样,改编后的名称虽然可以手工还原但是太麻烦,最好找到工具来做这一件事。前文,我们在查找swift相关的文件时看到一个工具:swift-demangle,下面我们就用它来demangle改编后的名称,看看可以得到什么。

 

首先,我们切换命令行到Xcode6的命令行工具:

  1. sudo xcode-select --switch /Applications/Xcode6-Beta.app/Contents/Developer 

 

然后,我们看看swift-demangle的命令行参数:

  1. USAGE: swift-demangle [options] [mangled name...] 
  2.  
  3. OPTIONS: 
  4.   -compact   - Compact mode (only emit the demangled names) 
  5.   -expand    - Expand mode (show node structure of the demangling) 
  6.   -help      - Display available options (-help-hidden for more) 
  7.   -no-sugar  - No sugar mode (disable common language idioms such as ? and [] from the output) 
  8.   -tree-only - Tree-only mode (do not show the demangled string) 
  9.   -version   - Display the version of this program 

 

从IDA中复制一个函数名,如:

  1. __TToFC9FuckSwift11AppDelegate26applicationDidBecomeActivefS0_FCSo13UIApplicationT_ 

 

我们执行如下命令:

  1. xcrun swift-demangle "__TToFC9FuckSwift11AppDelegate26applicationDidBecomeActivefS0_FCSo13UIApplicationT_" 

 

得到输出:

  1. _TToFC9FuckSwift11AppDelegate26applicationDidBecomeActivefS0_FCSo13UIApplicationT_ ---> @objc FuckSwift.AppDelegate.applicationDidBecomeActive (FuckSwift.AppDelegate)(ObjectiveC.UIApplication) -> () 

可以看到函数被还原。

 

到这里我们停下,看看Swift对越狱开发的影响:

1、目前无法使用class-dump得到ObjC的头文件。

2、MobileSubstrate应该还可以正常工作。

3、可以使用demangle工具还原函数名,后期这部分工作IDA可能会自动支持。

 

总之,对越狱开发的流程会稍微有影响,针对应用的越狱开发还可以存在。

 

下面我们看看命令行工具swift-ide-test的参数:

  1. OVERVIEW: Swift IDE Test 
  2.  
  3. USAGE: swift-ide-test [options] [input files...] 
  4.  
  5. OPTIONS: 
  6.   -D=<string>                              - Build configurations 
  7.   -F=<string>                              - add a directory to the framework search path 
  8.   -I=<string>                              - add a directory to the import search path 
  9.   -annotate-print                          - Annotate AST printing 
  10.   -code-completion-diagnostics             - Print compiler diagnostics while doing code completion 
  11.   -code-completion-token=<string>          - Code completion token name 
  12.   -comments-xml-schema=<string>            - Filename of the RelaxNG schema for documentation comments 
  13.   -enable-objc-factory-method-constructors - Implicitly import Objective-C factory methods as initializers 
  14.   -enable-objc-implicit-properties         - Implicitly import Objective-C getter/setter pairs as properties 
  15.   -explode-pattern-binding-decls           - Separate pattern binding decls into individual var decls 
  16.   -fatal-assembler-warnings                - Consider warnings as error 
  17.   -fully-qualified-types                   - Print fully qualified types 
  18.   -fully-qualified-types-if-ambiguous      - Print types fully-qualified if they would be ambiguous otherwise 
  19.   -function-definitions                    - Print function bodies 
  20.   -help                                    - Display available options (-help-hidden for more) 
  21.   -implicit-objc-with                      - Make the "with" implicit in initializers 
  22.   -import-objc-header=<string>             - header to implicitly import 
  23.   -module-cache-path=<string>              - Clang module cache path 
  24.   -module-print-hidden                     - Print non-exported imported or submodules 
  25.   -module-print-skip-overlay               - Skip Swift overlay modules 
  26.   -module-print-submodules                 - Recursively print submodules 
  27.   -module-to-print=<string>                - Name of the module to print 
  28.   -objc-bridge-dictionary                  - Bridge Dictionary<K, V> to NSDictionary 
  29.   -prefer-type-repr                        - When printing types, prefer printing TypeReprs 
  30.   -print-after-all                         - Print IR after each pass 
  31.   -print-before-all                        - Print IR before each pass 
  32.   Mode: 
  33.     -code-completion                       - Perform code completion 
  34.     -repl-code-completion                  - Perform REPL-style code completion 
  35.     -syntax-coloring                       - Perform syntax coloring 
  36.     -structure                             - Perform document structure annotation 
  37.     -annotate                              - Perform semantic annotation 
  38.     -test-input-complete                   - Check if input source is complete 
  39.     -print-ast-not-typechecked             - Print the non-typechecked AST 
  40.     -print-ast-typechecked                 - Print the typechecked AST 
  41.     -print-module                          - Print visible declarations in a module 
  42.     -print-types                           - Print types of all subexpressions and declarations in the AST 
  43.     -print-comments                        - Print documentation comments attached to decls 
  44.     -print-module-comments                 - Given a module, print documentation comments attached to decls 
  45.     -print-module-imports                  - Recursively print all imports visible from a particular module 
  46.     -print-usrs                            - Print USRs for all decls 
  47.     -parse-rest                            - Parse a ReST file 
  48.   -print-implicit-attrs                    - Print implicit attributes 
  49.   -print-regular-comments                  - Print regular comments from clang module headers 
  50.   -print-stats                             - Print statistics 
  51.   -sdk=<string>                            - path to the SDK to build against 
  52.   -skip-private-stdlib-decls               - Don't print declarations that start with '_' 
  53.   -skip-unavailable                        - Don't print unavailable declarations 
  54.   -source-filename=<string>                - Name of the source file 
  55.   -split-objc-selectors                    - Split Objective-C selectors 
  56.   -stats                                   - Enable statistics output from program (available with Asserts) 
  57.   -synthesize-sugar-on-types               - Always print Array and Optional with sugar 
  58.   -target=<string>                         - target triple 
  59.   -terminal                                - Use terminal color for source annotations 
  60.   -time-passes                             - Time each pass, printing elapsed time for each on exit 
  61.   -typecheck                               - Type check the AST 
  62.   -version                                 - Display the version of this program 

 

从参数上看,这很可能是Xcode的内部工具,用来做代码完成与检查的。这里不具体分析,感兴趣的兄弟可以自己试试。

 

下面我们继续回到 Swift 工具上,首先看看parse的输出,执行如下命令:

  1. xcrun swift AppDelegate.swift -dump-parse 

 

得到如下输出:

  1. (source_file 
  2.   (import_decl UIKit') 
  3.   (class_decl "AppDelegate" type='<null type>' inherits: <null>, <null
  4.     (pattern_binding_decl 
  5.       (pattern_typed 
  6.         (pattern_named 'window'
  7. )) 
  8.     (var_decl "window" type='<null type>' storage_kind='stored'
  9.     (func_decl "application(_:didFinishLaunchingWithOptions:)" type='<null type>' 
  10.       (body_params 
  11.         (pattern_typed implicit 
  12.           (pattern_named implicit 'self')) 
  13.         (pattern_tuple 
  14.           (pattern_typed 
  15.             (pattern_named 'application'
  16.             (type_ident 
  17.               (component id='UIApplication' bind=none))) 
  18.           (pattern_typed 
  19.             (pattern_named 'launchOptions'
  20. ))) 
  21.       (result 
  22.         (type_ident 
  23.           (component id='Bool' bind=none))) 
  24.       (brace_stmt 
  25.         (sequence_expr type='<null>' 
  26.           (unresolved_dot_expr type='<null>' field 'window' 
  27.             (declref_expr type='<null>' decl=AppDelegate.(file).AppDelegate.func decl.self@AppDelegate.swift:17:10 specialized=yes)) 
  28.           (assign_expr 
  29.             (**NULL EXPRESSION**) 
  30.             (**NULL EXPRESSION**)) 
  31.           (call_expr type='<null>' 
  32.             (unresolved_decl_ref_expr type='<null>' name=UIWindow specialized=no) 
  33.             (tuple_expr type='<null>' names=frame 
  34.               (unresolved_dot_expr type='<null>' field 'bounds' 
  35.                 (call_expr type='<null>' 
  36.                   (unresolved_dot_expr type='<null>' field 'mainScreen' 
  37.                     (unresolved_decl_ref_expr type='<null>' name=UIScreen specialized=no)) 
  38.                   (tuple_expr type='<null>')))))) 
  39.         (sequence_expr type='<null>' 
  40.           (unresolved_dot_expr type='<null>' field 'backgroundColor' 
  41.             (force_value_expr type='<null>' 
  42.               (unresolved_dot_expr type='<null>' field 'window' 
  43.                 (declref_expr type='<null>' decl=AppDelegate.(file).AppDelegate.func decl.self@AppDelegate.swift:17:10 specialized=yes)))) 
  44.           (assign_expr 
  45.             (**NULL EXPRESSION**) 
  46.             (**NULL EXPRESSION**)) 
  47.           (call_expr type='<null>' 
  48.             (unresolved_dot_expr type='<null>' field 'whiteColor' 
  49.               (unresolved_decl_ref_expr type='<null>' name=UIColor specialized=no)) 
  50.             (tuple_expr type='<null>'))) 
  51.         (call_expr type='<null>' 
  52.           (unresolved_dot_expr type='<null>' field 'makeKeyAndVisible' 
  53.             (force_value_expr type='<null>' 
  54.               (unresolved_dot_expr type='<null>' field 'window' 
  55.                 (declref_expr type='<null>' decl=AppDelegate.(file).AppDelegate.func decl.self@AppDelegate.swift:17:10 specialized=yes)))) 
  56.           (tuple_expr type='<null>')) 
  57.         (return_stmt 
  58.           (unresolved_decl_ref_expr type='<null>' name=true specialized=no)))) 
  59.     (func_decl "applicationWillResignActive(_:)" type='<null type>' 
  60.       (body_params 
  61.         (pattern_typed implicit 
  62.           (pattern_named implicit 'self')) 
  63.         (pattern_tuple 
  64.           (pattern_typed 
  65.             (pattern_named 'application'
  66.             (type_ident 
  67.               (component id='UIApplication' bind=none))))) 
  68.       (brace_stmt)) 
  69.     (func_decl "applicationDidEnterBackground(_:)" type='<null type>' 
  70.       (body_params 
  71.         (pattern_typed implicit 
  72.           (pattern_named implicit 'self')) 
  73.         (pattern_tuple 
  74.           (pattern_typed 
  75.             (pattern_named 'application'
  76.             (type_ident 
  77.               (component id='UIApplication' bind=none))))) 
  78.       (brace_stmt)) 
  79.     (func_decl "applicationWillEnterForeground(_:)" type='<null type>' 
  80.       (body_params 
  81.         (pattern_typed implicit 
  82.           (pattern_named implicit 'self')) 
  83.         (pattern_tuple 
  84.           (pattern_typed 
  85.             (pattern_named 'application'
  86.             (type_ident 
  87.               (component id='UIApplication' bind=none))))) 
  88.       (brace_stmt)) 
  89.     (func_decl "applicationDidBecomeActive(_:)" type='<null type>' 
  90.       (body_params 
  91.         (pattern_typed implicit 
  92.           (pattern_named implicit 'self')) 
  93.         (pattern_tuple 
  94.           (pattern_typed 
  95.             (pattern_named 'application'
  96.             (type_ident 
  97.               (component id='UIApplication' bind=none))))) 
  98.       (brace_stmt)) 
  99.     (func_decl "applicationWillTerminate(_:)" type='<null type>' 
  100.       (body_params 
  101.         (pattern_typed implicit 
  102.           (pattern_named implicit 'self')) 
  103.         (pattern_tuple 
  104.           (pattern_typed 
  105.             (pattern_named 'application'
  106.             (type_ident 
  107.               (component id='UIApplication' bind=none))))) 
  108.       (brace_stmt)))) 

 

由于不了解编译器相关的知识,无法解析上述输出,但是看起来很像common lisp 的“点对”数据结构。

 

另外,我们会注意到另一个比较重要的命令行参数:-repl,我们一起玩玩,看看这个工具能力怎么样。

 

在命令行执行如下命令:

  1. xcrun swift -repl 

 

可以得到一个脚本解析器的执行环境:

 

我们参考“The Swift Programming Language”写一个Hello World,看看效果:

 

可以使用:Ctrl + D退出解析器。

 

这里可以得到:

1、Swift既可以被编译执行,也可以被解析执行,是真正的动态语言。

2、大家可以用这个工具来学习语言特性。

 

就分析到这里,希望对大家有帮助。

 

推荐阅读:

Swift专题

CocoaChina是全球最大的苹果开发中文社区,官方微信每日定时推送各种精彩的研发教程资源和工具,介绍app推广营销经验,最新企业招聘和外包信息,以及Cocos2d引擎、Cocos Studio开发工具包的最新动态及培训信息。关注微信可以第一时间了解最新产品和服务动态,微信在手,天下我有!

请搜索微信号“CocoaChina”关注我们!

搜索CocoaChina微信公众号:CocoaChina

顶部