HOME » Natsu note » iOS » Xcode » [Xcode][Modern Objectice-C] NSNumberリテラルとBoxed Expression Literals

[Xcode][Modern Objectice-C] NSNumberリテラルとBoxed Expression Literals 2012/08/22/|iOS » Xcode

Xcode 4.4 (+ LLVM 4.0)からNSNumberリテラルが利用可能となりました(Modern Objective-C)。かなり便利でコード量も減らせます。

NSNumberリテラルによるオブジェクトの生成

まずは、オブジェクトの生成から。これまで、numberWithXxxまたはinitWithXxxを利用して生成していましたが、これからはNSNumberリテラルを利用して簡潔に書くことが可能です。NSNumberリテラルは、文字列リテラルと同様に@を使って表現します。

メソッドによる生成(従来の方法)

NSNumber *value;
value = [NSNumber numberWithChar:'X'];
value = [NSNumber numberWithInt:12345];
value = [NSNumber numberWithUnsignedLong:12345ul];
value = [NSNumber numberWithLongLong:12345ll];
value = [NSNumber numberWithFloat:123.45f];
value = [NSNumber numberWithDouble:123.45];
value = [NSNumber numberWithBool:YES];

NSNumberリテラルによる生成

NSNumber *value;
value = @'X';
value = @12345;
value = @12345ul;
value = @12345ll;
value = @123.45f;
value = @123.45;
value = @YES; // --- (注) または value = @(YES);

(注) BOOL値を表現する際には、objx/objc.hの内容によってはBoxed Expression Literalsを利用する必要があります(詳細は以下)。

Boxed Expression Literals

@の後ろに()を付けることで変数や式を入れることも可能です(Boxed Expression Literals)。これにより、例えば以下のような表現も可能となります。

メソッドによる生成

NSNumber *value = [NSNumber numberWithInt:num];
NSNumber *percent = [NSNumber numberWithDouble:ratio * 100.0];
NSNumber *portrait = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];

NSNumberリテラルによる生成

NSNumber *value = @(num);
NSNumber *percent = @(ratio * 100.0);
NSNumber *portrait = @(UIInterfaceOrientationPortrait);

BOOL型の生成

オブジェクトをBOOL値から生成する場合、objc/objc.hの内容によってはBoxed Expression Literalsを利用する必要があります。これは、YES, NOの定義に依存します。iOS 5.1 SDK, MAC OSX 10.7 SDKでは、YES, NOの定義は以下のようになっています。

#define YES             (BOOL)1
#define NO              (BOOL)0

したがって、Boxed Expression Literalsを利用しないと、

value = @(BOOL)1;

となってしまい、コンパイラエラーとなります。一方で、Mac OS 10.8 SDKでは以下のような定義になっています。

#define YES             ((BOOL)1)
#define NO              ((BOOL)0)

そのため、value = @YES; というような書き方が可能となるわけです。まとめると、BOOL値からオブジェクトを生成する際には、以下のような使い分けが必要です(Xcode4.4.1現在)。

// iOS SDK 5.1, MAC OSX 10.7 SDK
value = @(YES);

// MAC OSX 10.8 SDK
value = @YES;

まとめ

NSNumberリテラル、Boxed Expression Literalsを利用することで、NSNumber型オブジェクトの生成を簡潔に書くことができるようになります。ただし、BOOL値からの生成のように、マクロの定義によっては単純に@表記を利用しただけではエラーになることがあります。そのときは、必要に応じてBoxed Expression Literalsを使いましょう。

質問や間違い等の指摘はツイッターでお願いします。@natsun_happy

参考資料