Pergunta

Estou criando um jogo que usa cartões. Eu tenho uma classe AppController com uma instância na ponta. A instância AppController tem uma variável de instância NSArray chamado lista de palavras. Na inicialização, exemplo da ponta da AppController gera um novo gamecard. Cada gamecard tem uma matriz de palavras que contêm 5 palavras seleccionadas aleatoriamente a partir da lista na AppController. Como a lista é grande, eu gostaria de lê-lo na memória apenas uma vez. Portanto, eu quero apenas uma instância do AppController, como uma única classe. Cada vez que um novo gamecard é criado a partir de dentro AppController, deve acessar a mesma instância singleton para recuperar a lista de palavras. Então, basicamente, eu preciso de um singleton AppController que cria GameCards, onde cada gamecard tem uma referência para o AppController originais. Não tenho certeza de como implementar isso. Desculpe se a explicação era confuso.

Um exemplo de código que encontrei on-line segue ( http://numbergrinder.com/node/29 )

+ (AppController *)instance 
{
static AppController *instance;

@synchronized(self) {
    if(!instance) {
        instance = [[AppController alloc] init];
    }
}

return instance;
}

Mas quando eu tentei fazer algo com ele em uma instância gamecard através do código abaixo, o meu pedido levou uma eternidade para lançamento e Xcode me disse que era o carregamento 99797 quadros de pilha.

AppController *controller = [AppController instance];
Foi útil?

Solução

Parece que um loop infinito. Certifique-se de que -. [AppController Init] não está chamando + [instância AppController]

Outras dicas

Por que todas as necessidades cartão de uma referência para o controlador de aplicativo?

Se for apenas para acessar suas palavras, é mais simples para permitir que cada cartão de possuir diretamente suas palavras. Faça um novo método chamado initWithWords: o designado initializer para a classe gamecard. Inicializar cada cartão com a variedade de suas cinco palavras, e ter o cartão possuir essa matriz para sua vida.

A remoção referências dos cartões para o controlador aplicativo iria resolver o loop infinito que Tom astutamente detectado.

Além disso, se nenhuma palavra deve aparecer em dois cartões de uma vez, lembre-se de levar isso em conta na elaboração de Great Big matriz do controlador aplicativo de palavras, e quando destruindo cartões (você pode ou não pode querer as palavras para voltar na pilha para futuros cartões).

Parece que você está no caminho certo. Eu nunca tentei colocar uma referência a um singleton em um arquivo nib, no entanto. Você pode querer criar uma classe singleton separado que mantém uma cópia dos dados (DataManager, talvez?), E então chamá-lo de dentro de sua instância do AppController para buscar as palavras.

Você pode achar que colocar um singleton dentro de um nib (usando o código para um singleton no post de Stu) funciona muito bem, no entanto. Boa sorte!

Parece que você pode estar chamando seu método de classe instance de dentro do seu método init. Tente algo parecido com isto:

static AppController* _instance = nil;

- (id)init
{
    // depending on your requirements, this may need locking
    if( _instance ) {
        [self release];
        return _instance;
    }
    if( (self = [super init]) ) {
        _instance = [self retain];
        // do your initialization
    }
    return self;
}

+ (AppController*)instance
{
    if( _instance ) return _instance;
    else            return [[AppController alloc] init];
}

Isso garante que apenas uma instância do AppController está sempre disponível e também que ele é seguro para alocá-lo, bem como obter uma cópia através do método de classe instance. Não é o segmento de seguros, por isso, se ele vai ser acessado por vários segmentos, você deve adicionar algum bloqueio em torno das verificações para _instance.

O caminho normal para criar um AppController / AppDelegate é adicionar um costume NSObject ao seu arquivo MainMenu / MainWindow.xib. Defina a classe para ser AppController. Vincular sua referência delegado UIApplication / NSApplication ao seu objeto AppController. Então você pode obter o seu AppController único com qualquer

(AppController*)[NSApp delegate];

ou

(AppController*)[[UIApplication sharedApplication] delegate];

Você nunca tem que criá-lo com alloc / init, porque ele vai ser criado quando o aplicativo é iniciado. Você não tem que se preocupar com tornando-se um singleton porque ninguém nunca vai tentar criar outra. E você não precisa se preocupar em como acessá-lo, porque ele será o delegado do objeto UIApplication / NSApplication.

Tudo o que disse, se você precisar de uma variável global segurando uma série de palavras, em seguida, esquecer o AppController e fazer um novo objeto singleton que detém / lê a matriz. Caso em que você só precisa:

+ (NSArray *)sharedWordListArray 
{
    static NSArray *wordList;
    if( !wordList ) {
        wordList = [[NSMutableArray alloc] init];
        // read array
    }
    return wordList;
}

Se você realmente precisa enfiar a segurança, em seguida, basta chamar [WordList sharedWordListArray] de applicationDidFinishLaunching do seu delegado app: método antes de iniciar qualquer segmentos, ou adicionar um NSLock se você realmente quer para adiar o carregamento para mais tarde, mas muitas vezes a sua melhor tomar o tempo de carregamento atingiu no início do programa, em vez de forma inesperada quando o usuário toma alguma ação mais tarde.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top