(對於在ViewController之間傳值)最簡單最專業的方法就是所謂的執行個體共用(shared instance)。基本的做法就是在最初調用的時候建立一個可以執行個體化這個類的單例的類方法(singleton),然後在接下來的調用中返回這個執行個體。
我們用一個棋盤遊戲中常見的Engine類來舉例說明:
Engine.h
[plain] view plaincopy
- #import
- @interface Engine : NSObject {
- NSUInteger board[100]; // c-style array
- }
-
- + (Engine *) sharedInstance;
-
- - (NSUInteger) getFieldValueAtPos:(NSUInteger)x;
- - (void) setFieldValueAtPos:(NSUInteger)x ToValue:(NSUInteger)newVal;
-
- @end
Engine.m
[plain] view plaincopy
- #import "Engine.h"
-
- @implementation Engine
-
- static Engine *_sharedInstance;
-
- - (id) init
- {
- if (self = [super init])
- {
- // custom initialization
- memset(board, 0, sizeof(board));
- }
- return self;
- }
-
- + (Engine *) sharedInstance
- {
- if (!_sharedInstance)
- {
- _sharedInstance = [[Engine alloc] init];
- }
-
- return _sharedInstance;
- }
-
- - (NSUInteger) getFieldValueAtPos:(NSUInteger)x
- {
- return board[x];
- }
-
- - (void) setFieldValueAtPos:(NSUInteger)x ToValue:(NSUInteger)newVal
- {
- board[x] = newVal;
- }
-
- @end
然後我們只需import這個類到我們的app delegate中同時加上如下幾行代碼:
[plain] view plaincopy
- // at the top: #import "Engine.h"
-
- Engine *myEngine = [Engine sharedInstance];
-
- [myEngine setFieldValueAtPos:3 ToValue:1];
-
- NSLog(@"pos 3: %d",[myEngine getFieldValueAtPos:3]);
- NSLog(@"pos 2: %d",[myEngine getFieldValueAtPos:2]);
你會發現你並沒有alloc-init這個類,只是不斷地取sharedInstance指標。實際上這個類方法在第一次調用時會建立一個執行個體,並將其儲存在靜態變數中。
你不必擔心release的問題,因為所有app佔用的記憶體空間將在其退出時被清空。但如果你想做得更好,你可以把sharedInstance的release放到app delegate的dealloc方法中。不過我發現這個dealloc其實從來沒有被調用過。我猜測是因為IOS認為kill掉這個app並釋放記憶體空間會更快速。
你還可以把其他與Engine類有關的方法和資料變數放入Engine類中。只是不要加入任何有關顯示它的內容。這樣Engine才能被重複使用。