[英]Design pattern for waiting for user interaction in iOS?
我正在為iOS開發BlackJack游戲。 跟蹤當前狀態和需要執行的操作變得越來越困難。 例如,我有一個C ++類來跟蹤當前的Game:
class Game {
queue<Player> playerQueue;
void hit();
void stand();
}
目前,我正在使用事件(方法A)實現它:
- (void)hitButtonPress:(id)sender {
game->hit();
}
void Game::hit() {
dealCard(playerQueue.top());
}
void Game::stand() {
playerQueue.pop();
goToNextPlayersTurn();
}
隨着越來越多的選項添加到游戲中,為每個事件創建事件變得乏味且難以跟蹤。
我想到的另一種實現方式是這樣(方法B):
void Game::playersTurn(Player *player) {
dealCards(player);
while (true) {
string choice = waitForUserChoice();
if (choice == "stand") break;
if (choice == "hit")
dealCard(player);
// etc.
}
playerQueue.pop();
goToNextPlayersTurn();
}
其中, waitForUserChoice
是一個特殊功能,可讓用戶與UIViewController
進行交互,並且一旦用戶按下按鈕,則只有將控制權返回給playersTurn
函數。 換句話說,它將暫停程序,直到用戶單擊按鈕。
使用方法A,每次需要用戶交互時,我都需要拆分功能。 方法B讓一切保持更多控制。 本質上,方法A和方法B之間的區別如下:
A:
function A() {
initialize();
// now wait for user interaction by waiting for a call to CompleteA
}
function CompleteA() {
finalize();
}
B:
function B() {
initialize();
waitForUserInteraction();
finalize();
}
注意B如何使代碼更有條理。 有沒有辦法用Objective-C做到這一點? 還是有我沒有提到過的另一種推薦方法?
我能想到的第三個選擇是使用有限狀態機。 我已經聽到了一些關於它們的信息,但是我確定在這種情況下是否對我有幫助。
我的問題的推薦設計模式是什么?
我了解您遇到的困境。 當我第一次啟動iOS時,我非常費力地放棄放棄與操作系統之間的控制權。
通常,iOS會鼓勵您使用方法A。通常,您的ViewController中有在方法A()中設置的變量,然后在CompleteA()中對其進行檢查,以驗證是否首先運行A()。
關於您關於有限狀態機的問題,我認為這可以幫助您解決問題。 我在iOS中寫的第一件事是FSM(這是非常糟糕的代碼),但是您可以在這里看看(在FlipsideViewController.m的底部附近):
https://github.com/esromneb/ios-finite-state-machine
一般的想法是將其放在@interface塊中的.h文件中
static int state = 0;
static int running = 0;
在您的.m中,您有以下內容:
- (void) tick {
switch (state) {
case 0:
//this case only runs once for the fsm, so setup one time initializations
// next state
state = 1;
break;
case 1:
navBarStatus.topItem.title = @"Connecting...";
state = 2;
break;
case 2:
// if something happend we move on, if not we wait in the connecting stage
if( something )
state = 3;
else
state = 1;
break;
case 3:
// respond to something
// next state
state = 4;
break;
case 4:
// wait for user interaction
navBarStatus.topItem.title = @"Press a button!";
state = 4;
globalCommand = userInput;
// if user did something
if( globalCommand != 0 )
{
// go to state to consume user interaction
state = 5;
}
break;
case 5:
if( globalCommand == 6 )
{
// respond to command #6
}
if( globalCommand == 7 )
{
// respond to command #7
}
// go back and wait for user input
state = 4;
break;
default:
state = 0;
break;
}
if( running )
{
[self performSelector:@selector(tick) withObject:nil afterDelay:0.1];
}
}
在此示例中(從github上的示例進行了修改),globalCommand是一個表示用戶輸入的int。 如果globalCommand為0,則FSM只會旋轉到狀態4,直到globalCommand不為零。
要啟動FSM,只需將運行設置為1,然后從viewController調用[self tick]。 FSM將每隔0.1秒“滴答”一聲,直到運行設置為0。
在我最初的FSM設計中,我不得不響應運行其自己軟件的Windows計算機的用戶輸入和網絡輸入。 在我的設計中,Windows PC也運行類似但不同的FSM。 對於此設計,我使用NSMutuableArray構建了兩個命令的FIFO隊列對象。 用戶交互和網絡數據包會將命令排入隊列,而FSM將使項目出隊並對其進行響應。 我最終使用https://github.com/esromneb/ios-queue-object作為隊列。
如果您需要任何說明,請發表評論。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.