2013年5月29日水曜日

Objective-C の新文法 (modern syntax) について


Objective-C の仕様は近年急激に変化しています.

  • Objective-C 2.0 (2006, Leopard)
  • Objective-C 2.0 with Blocks (2009, Snow Leopard)
  • Modern Objective-C (2011, Lion)

また,ランタイムのほうも2005年のTigerで一段落したかと思いきや,その後ガーベージコレクタを入れたり非推奨にしたりとめまぐるしく仕様が変わっています.ここらへんは OS X だけでなく iOS とも歩調を合わせるために致し方の無いことかもしれません.

さて,Lionから導入された Objective-C の modern syntax ですが,この新文法を使うことにより非常に簡潔にプログラムが書けるようになりました.

極端な例を挙げますと,

#import <Foundation/Foundation.h>

@interface PointObject: NSObject
@property float x;
@property float y;
@end

@implementation PointObject
@end

これだけで,2次元ベクトルクラスが書けます.次のように使います.

int main() {
  PointObject *p = [[PointObject alloc] init];
  p.x = 100;
  p.y = 200;
  NSLog(@"x: %f, y: %f", p.x, p.y);
  return 0;
}

もちろん Key-Value-Observing に対応します.元の PointObject クラスに一切触れること無く,プロパティの変更を外部に通知させることが出来ます.

#import <Foundation/Foundation.h>

@interface PointObject: NSObject
@property float x;
@property float y;
@end

@implementation PointObject
@end

@interface PointObserver: NSObject
@end

@implementation PointObserver
- (void)observeValueForKeyPath: (NSString *)keyPath
                      ofObject: (id)object
                        change: (NSDictionary *)change
                       context: (void *)context
{
  PointObject *p = (PointObject *)object;
  NSLog(@"x: %f", p.x);
}
@end

int main() {
  PointObject *p = [[PointObject alloc] init];
  PointObserver *o = [[PointObserver alloc] init];
  [p addObserver: o 
      forKeyPath: @"x"
         options: NSKeyValueObservingOptionInitial
         context: nil];
  p.x = 100;
  p.y = 200;
  NSLog(@"x: %f, y: %f", p.x, p.y);
  return 0;
}

実行結果は次のようになります.

2013-05-28 14:29:05.719 test[11088:707] x: 0.000000
2013-05-28 14:29:05.721 test[11088:707] x: 100.000000
2013-05-28 14:29:05.721 test[11088:707] x: 100.000000, y: 200.000000

0 件のコメント:

コメントを投稿