2012年2月6日月曜日

NSNumberクラスとプリミティブ型との変換


元々はこの記事を書こうと思ってたんだった。
脱線してObjective-Cの整数と32bit64bitの記事が一個forkした。
まあ、この記事も元々はCoredataのNSManagedObjectのプロパティの型ではまったことによるforkです。

Objective-Cのコレクションクラス(NSArrayやNSDictionary)ではid型(オブジェクト型)しか扱えないため
NSIneger等のプリミティブ型を扱う際にはNSNumber型に変換する必要がある。
そこで、下記の相互変換についてメモとしてまとめておくことにした。
  • NSInteger
  • int
  • NSNumber

以下、基本的にMac-OS-X 64bit向け。
iOS環境では、NSIntegerの取る型が異なるため、NSLogのString Format Specifiersが異なる。
値が代入されていないと、%@でNSIntegerはエラーにならないが
値が代入されていると、"EXC_BAD_ACCESS"となって実行時エラーとなる。


初期値について


初期化していない状態での初期値は、NSNumberはオブジェクト型なので「nil」、intは「0」となる。
NSIntegerはオブジェクト型として評価すると「nil」、整数として評価すると「0」となる。


int <-> NSInteger


NSInteger -> int はキャストすれば良い。
キャストしないと警告が出るのは"Objective-Cの整数と32bit64bit"で書いた通り。

一方で、int -> NSIntegerはキャストは不要。
理由はざっくりな説明だと、NSIntegerがintをくるんでいるため
下位概念のものを上位概念のものに入れることになるから、かと。


NSInteger <-> NSNumber


NSInteger -> NSNumberについては、NSNumberクラスのメソッドを使用する。
クラスメソッドを使用するパターンとalloc initするパターンがある。

NSNumber -> NSIntegerについてもintegerValueメソッドでOK。


int <-> NSNumber


このパターンについては、NSInteger <-> NSNumberとメソッドが微妙に変わるだけ。



整数以外のfloatやdoubleも基本的には同じなので割愛。

サンプルプロジェクトを以下のGithubで公開。
https://github.com/k-ori/objc-nsnumber-primitive-convert-samples

xcodeからのGithub連携でいいサイトが無かったので、それも後で書く。

■参照ページ
https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Strings/Articles/formatSpecifiers.html
https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/Reference/Reference.html

http://peterszwach.blogspot.com/2011/03/github-xcode-4.html

0 件のコメント:

コメントを投稿