Mountain Lion発表とともにリリースされたXcode4.4。OSX Lionでも使える様になっています。Xcode4.4から、llvm (コンパイラ)のバージョンが4.0になっています。
それによってObjective-Cの書き方にかなりの改善が加えられたので、それを簡単にまとめておきたいと思います。これらの改善は、iOS6に関係なく動作するので、いま作っている、iOS5用のコードにも使用出来ます。
synthesize by default
コンパイラが@synthesizeを補完してくれる様になったため、基本的な状況では、@synthesizeを書かなくてよくなりました。また、synthesizeされる相手のivarも、同名の変数ではなくて、アンダーバーを最初に付けた物がデフォルトとなります。これまで議論されて来たことがappleのコンパイラによって、これからは定義されているため、安心ですね。ちなみに、これは以前からですが、(strong)というのも,デフォルトがstrongなので、書かなくてよくなりました。
以前の書き方
// ViewController.h
@property (strong) NSString* testString;
// ViewController.m
@synthesize testString = _testString;
Modern Objective-C
// ViewController.h
@property NSString* testString;
Object Literals オブジェクトのリテラル
NSNumber, NSArray, NSDictionary が、@リテラルを使用して簡単に書ける様になりました。ArrayやDictionaryの定義の際に忘れがちだった、nil終結がいらないのも嬉しいですね。
以前の書き方
NSNumber*num = [NSNumber numberWithInt:100];
NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:@"value1",@"key1",@"value2",@"key2",nil];
NSArray* array = [NSArray arrayWithObjects:@"array1",@"array2",nil];
Modern Objective-C
NSNumber*num = @100;
NSDictionary *dic = @{@"key1":@"value1",@"key2":@"value2"};
NSArray* array = @[@"array1",@"array2"];
こんな感じで、いろいろな書き方も出来ますね。
NSNumber*num = @100;
NSNumber*num2 = @([num intValue] + 1);
NSDictionary *dic =@{@"key1":@"value1",@"key2":num2};
NSArray* array = @[num, dic];
ちなみに、NSMutableDictionary, NSMutableArrayにデータを作成する際は、mutableCopyを最後に付けてあげる必要があります。
NSNumber*num = @100;
NSMutableDictionary *dic =[@{@"key1":@"value1",@"key2":@"value2"} mutableCopy];
NSMutableArray* array = [@[num, dic] mutableCopy];
Modern Objective – C へのコンバート
Xcodeのタスクバーメニューから、Edit-Refactor-Convert to Modern Objective-C Syntax… というメニューが出来て、最新のObjective-Cの記述に変換してくれるオプションが出来ました。これで変換したいファイルを選択して、コンパートで来ます。(変換したくないファイルも選ぶことが出来る。)
ここにある様に、これまでのコードを、どのように書き換えることが出来るか見ることが出来るので、助かりますね。ただ、@synthesizeの変換は行ってくれなかったようなので、それは手動で行う必要があります。これまでも _ を前に付けて行っていた場合は、削除するだけですっきりですね。
クラスないでのメソッドの順序
これも、Xcode3.3からですが、クラス内で、後に宣言されるメソッドを使用するためには、無名カテゴリなどで最初に宣言しておく必要がありました。しかし、それも、クラス内の後に宣言していれば、メソッドの宣言はいらなくなりました。
以前の書き方
// ViewController.m
@interface ViewController()
-(void)originalMethod;
@end
-(void) test{
[self originalMethod];
}
-(void)originalMethod{
}
Modern Objective-C
// ViewController.m
-(void) test{
[self originalMethod];
}
-(void)originalMethod{
}
Xcode 4.4 でエラーになったケース
blocks内で、ivarに、アクセスするために、weakポインタに対して、obj->ivar というかたちで書いていたのですが、
/Users/tomohisa/Desktop/test44/test44/test44/ViewController.m:37:5: Dereferencing a __weak pointer is not allowed due to possible null value caused by race condition, assign it to strong variable first
というエラーで怒られる様になりました。なので、無名カテゴリでプロパティを定義する方法に変えようと思います。
以前の書き方
// ViewController.m
@implementation ViewController{
int a;
}
-(void) test{
__weak ViewController *wself = self;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// ...
wself->a = 1;
});
}
Modern Objective-C
// ViewController.m
@interface ViewController ()
@property int a;
@end
@implementation ViewController
-(void) test{
__weak ViewController *wself = self;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// ...
wself.a = 1;
});
}
終わりに
メニューの名前にもなっている、”Modern Objective-C”というのが、キーワードのようですね。ここ数年で、Objective-Cには大きな変更がたくさん入れられてiOS4時代の常識と、iOS5以降の時代の常識は全く変わりつつありますね。便利になって、コードが書きやすくなっているのは素晴らしいと思います。なにか他にあれば追加していきたいと思います。
こちらに、コード記述記法について追加しました。
ARC+Blocks+llvm4.0時代のコード記述作法 | Zero4Racer PRO Developer’s Blog
「今日からライオンでも使える!Xcode4.4 Modern Objective-C Syntaxでコードをきれいにする方法」への2件のフィードバック