InterfaceBuilderとイベント処理

IBで作成したオブジェクトを参照する

プログラムは、IBOutletを宣言したインスタンス変数(アウトレット)を通して、IBで作成したオブジェクトを参照することができる。プログラム側のヘッダファイルで以下のようにアウトレットを宣言する。

#import <UIKit/UIKit.h>
 
@interface DigitalClock1ViewController : UIViewController {
	// インスタンス変数の宣言
	UILabel *label;
}
@property(nonatomic, retain) IBOutlet UILabel *label;
@end

@propertyで記述されたアクセサに関しては、@implementation部に以下の記述が必要。

@synthesize label;

アウトレットがIB上のどのパーツを参照するのかはInterfaceBuilderで規定する。File’s Ownerを右クリックして先ほど宣言したアウトレットを選択し、これをView上の任意のパーツまでドラッグすることで、アウトレットとパーツとの参照関係が規定される。

オブジェクトに対するアクションを受け取る

ボタンが押された等のアクションをプログラム側で受け取る場合は、アクションを受け取るメソッドにIBActionを宣言する。プログラム側のヘッダファイルで以下のようにIBActionメソッドを宣言する。

#import <UIKit/UIKit.h>
 
@interface DigitalClock1ViewController : UIViewController {
}
 
- (IBAction) doKeyDown: (id) sender;
 
@end

また、@implementationにてメソッドを実装する。

- (IBAction) doKeyDown: (id) sender{
	// sender tagでアクションの発生したオブジェクトを特定することが可能
	NSLog:@"%d", [sender tag];
}

IBActionがIB上のどのパーツのアクションを受け取るのかはInterfaceBuilderで規定する。File’s Ownerを右クリックして先ほど宣言したメソッドを選択し、これをView上の任意のパーツまでドラッグすることで、IBActuionとパーツとの参照関係が規定される。

@propertyとアクセサ

クラス内のインスタンス変数をIB(や他のクラス)で利用する場合、IBより値が参照できるようにアクセサ(putter, getter)を各クラスで実装しておく必要がある。しかし@propertyを記述することで、実際のアクセサを実装しなくても値の参照が可能となる。

#import <UIKit/UIKit.h>
 
@interface DigitalClock1ViewController : UIViewController {
	// インスタンス変数の宣言
	UILabel *label;
}
@property(weak, nonatmic) IBOutlet UILabel *label;
@property(strong, nonatmic) NSString *str;
@end

@propertyのあとの属性はいくつでも指定できる。

属性 挙動
nonatomic スレッドセーフじゃないけど動作は早い?
weak 弱参照。参照先のObjectは、強参照しているObjectが無くなると消滅する
strong 強参照。強参照している間は、対象先のObjectは消滅しない

Storyboad上のObjectはViewController自身が間接的に強参照している、したがってIBOutletで再度ダイレクトに強参照する必要は無い。ただしViewControllerが管轄していないObjectに関しては、Storyboad上にあったとしても強参照しなければならない場合がある。Storyboad以外のObjectを参照する場合も同様に強参照すべきかどうか検討する必要がある。

@synthesize label;

最後に@implementationに@synthesizeを記入することで、getメソッドとputメソッドが自動的に実装される

self.str = nil;
[self setLabel:nil];

viewUnloadedメソッドで各Objectの解放を行う