簡體   English   中英

在iOS中等待用戶交互的設計模式?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM