Swift プログラミング

プログラミングで出逢った出来事

Xcode の Swift アプリでは、いちばん最初に実行される main 関数が暗黙的に宣言されています。

それについてと、明示的に実装する方法を調べてみました。

Swift での main 関数の実装方法と起動時引数の扱い方

Xcode のSwift言語 では、main.swift という名前のファイルを作成することで、従前のObjective-C言語 でいうmain関数 を実装できます。

main関数 を実装する

冒頭でも触れたように、Swift言語 ではmain.swift ファイルをプロジェクトに作成することで、そのファイル内の全体が暗黙的にmain関数 として使用されます。

import Foundation

println("TEST")

exit(0)

このように、main関数 を明示的に定義することなく、トップレベルに直接書いたソースコードが、最初のプログラムとして実行されます。

終了コードを返すには

これまでのmain関数 では終了状態をint型 の値で返すのが普通ですが、Swift言語 でもそれは同じです。

ただし、コードをトップレベルに直接書くスタイルのため、ここでreturn を使うことはできません。 Swift言語 で終了コードを添えてプログラムの実行を終了するにはexit関数 を使用します。

この引数に終了コードを添えることで、そこでアプリが終了し、実行元に終了コードが通知されます。

main.swift ファイルを省略する方法

iOS アプリではmain.swift ファイルを用意しなくても、AppDelegateクラス@UIApplicationMainディレクティブ を使うことで、main関数 を自動実装できるようになっています。

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

	var window: UIWindow?

このようにすることで、このクラスをデリゲートとして使用して初期 UI を起動するmain関数 が自動的に実装されます。

具体的には、次のようなコードと同等の動きをするようです。

import UIKit

exit(UIApplicationMain(Process.argc, Process.unsafeArgv, nil, NSStringFromClass(AppDelegate)))

この@UIApplicationMainディレクティブUIKit をインポートすることで利用できます。

実行時に渡された引数の扱い方について

これまでのmain関数 を独自に定義する方法であれば、実行時に渡されたコマンドライン引数をmain関数 の引数で受け取って処理することができました。

ただしSwift言語 の場合はmain関数 が定義されないため、関数の引数としてその値を受け取ることはできません。

C言語 互換な引数の扱い

そのため、Swift言語 では、自動的に定義される変数C_ARGC変数C_ARGV を使って引数を扱えるようになっています。

これらはそれぞれ、CInt型UnsafeMutablePointer<UnsafeMutablePointer<Int8>>型 で定義されていて、それぞれが、従来のmain関数 の引数で受けるときと同じC言語int型char**型 に相当しています。

Objective-C言語 的な引数の扱い

Swift言語Objective-C言語 と相互運用できるようになっているので、Objective-C言語 でおなじみのNSProcessInfoクラス を使って、コマンドラインから受け取った引数を扱うこともできます。

let arguments = NSProcessInfo.processInfo().arguments

for argument in arguments
{
	println(argument)
}

たとえばこのようにすることで、コマンドライン引数に渡された値を順次表示するようなコードも簡単に書けます。

受け取った引数をC言語 の関数に渡したい場合以外は、こちらの書き方の方が扱いやすくて良いかもしれませんね。