Objective-C コマンドライン引数 【初級編 第21回】

この記事は2013年2月5日に書かれたものです。内容が古い可能性がありますのでご注意ください。


コマンドライン引数

プログラム実行時に値を渡す

前回までObjective-Cにおける文字列の取り扱いについて取り上げてきました。
ここまでのソースコードは、「main.m」内部に体重と身長、そして名前を書いていました。これでは違う人のBMI値を出そうと
するとその都度ソースを書き換えて、コンパイルし直すということになります。
これは面倒なのでソース内に書き込むのではなく、外部から値を渡したいと思います。
このとき渡す方法として、ファイルから読み込むとかありますが今回はプログラム起動時に値を渡すようにしたいと思います。
これを実現するためにコマンドライン引数というものがあります。

コマンドライン引数

コマンドライン引数というのは、アプリケーションの起動時にmain関数に渡すことのできる引数です。
今までのコードではmainメソッドの引数はvoidでした。引数はなしということです。
このvoidのところで代わりに引数を指定するとアプリケーション実行時にmain関数に値を渡すことができます。
そしてNSProcessInfoというクラスを使用してその値を取得します。
このクラスですが現在のプロセスの情報を取得するメソッドです。今回の目的はコマンドライン引数を使用することですが、
コマンドライン引数以外にも環境変数やホスト名やプロセス名が所得することができます。
今回はコマンドライン引数なので「arguments」メソッドというメソッドを使用します。
このメソッドは以下のように定義されています。

- (NSArray *) arguments

戻り値を見てもらうと<Objective-C NSArray 配列 【初級編 第20回】>で紹介したNSArrayになっています。
このメソッドを使用するとコマンドラインで指定した引数が配列に格納されることになります。
「-」がついているということはインスタンス化メソッドなのでインスタンス化しなければ使用できません。
このクラスにはそのためのクラスファクトリメソッドが用意されているので[alloc」+イニシャライザというようなやり方は
使用しません。
クラスファクトリメソッドというのは、メモリの割り当てと初期化を行い、そのクラス自身のオブジェクトを返してくれるという
処理を一気に行ってくれるメソッドです。
メモリの割り当てをした場合、解放処理が気になるところですが自動解放に登録されます。
以下のようになっています。クラスの方で自信をオブジェクト化して返してくれるわけですね。

+ (NSProcessInfo *) processInfo

コードでの確認

では実装してみましょう。
main.m

#import <Foundation/Foundation.h>
#import <Foundation/NSObject.h>
#import "Bmi.h"
#import "Person.h"
#import "Manage.h"

int main(int argc, const char *argv[]){

    double weight;
    double height;
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    NSArray *arguments = [[NSProcessInfo processInfo] arguments];
    NSString *name = [[NSString alloc] initWithString:[arguments objectAtIndex:1]];
    weight = [[arguments objectAtIndex:2] doubleValue];
    height = [[arguments objectAtIndex:3] doubleValue];
    Person *person = [[Person alloc] initWithWeight:weight height:height name:name];
    printf("Person name:%sn",[[person name] UTF8String]);
    Manage *manage = [[Manage alloc] init];
    [manage setPerson:person];
    [person release];
    [manage showBestPerson];
    [manage release];
    [name release];
    [pool drain];
    return 0;
}

main.mのところだけ付け加えています。
7行目で今まで「void」となっていたところに引数を指定しています。int型の「args」には引数の総数が入ります。
char型のポインタの配列である「args[]」に実際の引数が格納されます。
12行目で「NSProcessInfo」クラスにprocessInfoメッセージを送信してインスタンスを作成し、
できたオブジェクトに対してargumentsメッセージを送り、コマンドライン引数を取得しています。
13行目はNSArrayオブジェクトから値を出しているわけですが、indexで1を指定しています。
配列の先頭であれば0となるのですが、コマンドライン引数はindexが1のところから格納されます。そのため先頭ではなく
2つ目の要素(indexは1です)から取り出しています。
weightやheightも同様ですね。身長体重はdouble型で定義されているので「doubleValue」メッセージを送信することで
型変換を行っています。
実装を見てもらうとこのコードは実行の際に名前、体重、身長の順で指定する必要があるのがわかると思います。
ちなみにindexが0には何が入るのかというとプログラム名が入ります。
後は今までの処理とかわりません。

結果確認

では実行してみましょう。
Objc21_1

プログラム実行時に名前、体重、身長の順に引数を指定しています。
指定した値が表示されていますね。
このようにプログラム実行時に何か値を指定したいといったときにコマンドライン引数というものを使用します。

まとめ

今回のまとめとしては
・プログラム実行時に値を渡したいときにコマンドライン引数を使用する
・Objective-Cでコマンドライン引数を取得するときはNSProcessInfoクラスを使用する
・NSProcessInfoクラスはクラスファクトリメソッドというものを持っており、そのメソッドを使用することで
メモリ割り当て、初期化といった処理を行ってくれる
・NSProcessInfoクラスではコマンドライン引数以外の値も取得できる
・NSProcessInfoクラスのメソッドによりコマンドライン引数で指定した引数は配列に格納されるが、引数で指定したものは
indexの1から格納され、先頭にはプログラム名が格納される
といったところでしょうか。

  • このエントリーをはてなブックマークに追加

PAGE TOP