2015年04月10日

NSIntegerの出力時フォーマット指定文字はどうするのが正解か?32bit/64bit

今となってはいささか旧聞に属する内容かもしれないがちゃんと記録しておいたほうがいいと思うので。

もうそろそろ32bitアプリの開発をする人がいなくなって、64bitオンリーになりつつあるのかもしれません。が、もしかしたらまだ32bit/64bit両方メンテナンスを続けている人もいるかも。私もそんなレガシー同盟の一人です。

Objective-Cでプログラムを各場合に整数値を保存する整数にはint型よりもNSInteger型を使うのが一般的です。これはアップルの提供するフレームワーク内のメソッドがNSInteger型を使っていることが多いからです。アップルとしては将来APIを変更する必要があった場合でも容易に型変更ができるようにとintではなくNSIntegerを使っているのだと思います。

NSInteger型はコンパイラの設定によって実際のC言語の型が変わります。
32bit環境:int
64bit環境:long
ここでそれぞれのサイズはどうなっているのでしょうか?

32bit環境:int型=32bit、long型=32bit ∴NSInteger型=32bit
64bit環境:int型=32bit、long型=64bit ∴NSInteger型=64bit

この変数を出力するときに32bit時代であれば普通はこうしていました。

NSInteger i = 101;
NSLog(@"%d",i);


ところが、このコードを64bitモードでコンパイルしようとするとlong型を%dで受けようとしているので警告が出ます。

だからと言って64bit用にするにはこうなりますが

NSInteger i = 101;
NSLog(@"%ld",i);


これだと、32bitモードではintを%ldで受けることになるのでやはり警告になります。

この2つを両立するやり方が求められます。

一時は

NSInteger i = 101;
NSLog(@"%@",@i);

のようなトリッキーなやり方が流行りました。これはNSIntegerをNSNumberにラップしてオブジェクトとして値を出力させるやり方でオブジェクトの生成がされますが、デバッグプリントなどログ出力目的であればまったく気にする必要はないでしょう。

が、現在は下記のように対応するのがアップルの公式です。

NSInteger i = 101;
NSLog(@"%ld",(long)i);


わかってみたら単純な話です。これも32bit環境下ではキャストするコストがかかりますが、64bitではゼロコスト。将来的には32bitはなくなる話ですから単純でとてもいい方法です。



nsinteger.png

32bit

2015-04-10 17:24:29.708 Code Test[16891:3232692] NSInteger 4
2015-04-10 17:24:29.709 Code Test[16891:3232692] long 4
2015-04-10 17:24:29.709 Code Test[16891:3232692] int 4
2015-04-10 17:24:29.710 Code Test[16891:3232692] 101


64bit

2015-04-10 17:25:16.988 Code Test[16899:3233474] NSInteger 8
2015-04-10 17:25:16.989 Code Test[16899:3233474] long 8
2015-04-10 17:25:16.990 Code Test[16899:3233474] int 4
2015-04-10 17:25:16.990 Code Test[16899:3233474] 101



Swiftで書く人はそもそもこんな面倒なことを考える必要もないんでしょうね。そしてObjective-Cでも32bit意識しない日ももうまもなく来ることでしょう。
posted by 永遠製作所 at 19:16| 東京 ☁| Comment(1) | TrackBack(0) | iPhone/iPod touch | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
%zdってのもありましたね。
ttp://qiita.com/annaok/items/bf1c80184dac8a9945c2
Posted by at 2015年04月11日 12:21
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント: [必須入力]

※ブログオーナーが承認したコメントのみ表示されます。
この記事へのトラックバックURL
http://blog.seesaa.jp/tb/417090884
※ブログオーナーが承認したトラックバックのみ表示されます。
※言及リンクのないトラックバックは受信されません。

この記事へのトラックバック