questões tornam um objeto persistente em Objective C
-
18-09-2019 - |
Pergunta
A tentativa de fazer um NSObject chamado 'pessoa' que irá realizar os detalhes de login para o meu pedido (nada a fantasia). A aplicação é feita de um controlador de navegação com múltiplas visões de mesa, mas estou tendo problemas compartilhando o objeto Person redor.
tentou criar um objeto estático como este:
+ (Person *)sharedInstance {
static Person *sharedInstance;
@synchronized(self) {
if(!sharedInstance)
sharedInstance = [[Person alloc] init];
return sharedInstance;
}
return nil;
}
E aqui é o cabeçalho
// Person.h
#import <Foundation/Foundation.h>
@interface Person : NSObject {
NSString *fullName;
NSString *firstName;
NSString *lastName;
NSString *mobileNumber;
NSString *userPassword;
}
@property(nonatomic, retain) NSString *fullName;
@property(nonatomic, retain) NSString *firstName;
@property(nonatomic, retain) NSString *lastName;
@property(nonatomic, retain) NSString *mobileNumber;
@property(nonatomic, retain) NSString *userPassword;
+ (Person *)sharedInstance;
-(BOOL) setName:(NSString*) fname;
-(BOOL) setMob:(NSString*) mnum;
-(BOOL) setPass:(NSString*) pwd;
@end
Este objeto setters e getters são necessários em diferentes partes da aplicação. Tenho vindo a tentar acessá-los como este
Person * ThePerson = [[Person alloc] init];
ThePerson = nil;
NSString * PersonsName;
PersonsName = [[Person sharedInstance] firstName];
Tudo funciona bem na tela de login, mas ele morre na próxima utilização. geralmente EXC_BAD_ACCESS (eek!).
É evidente que eu estou fazendo algo muito errado aqui. Existe uma maneira mais fácil de objetos de acções entre os diferentes controladores número um vista (ambos codificados e xib)?
Solução
Por que não armazenar essas informações na NSUserDefaults
ou o chaveiro?
Outras dicas
Seu método de +sharedInstance
retornos nil
quando deve voltar a instância compartilhada. Além disso, eu duvido que haja qualquer valor para sincronizar naquele bloco. O método poderia ser escrito de forma mais simples:
+ (Person *)sharedInstance {
static Person *sharedInstance;
if(!sharedInstance) {
sharedInstance = [[Person alloc] init];
}
return sharedInstance;
}
Note que esta não cria um 'objeto estático', já que não há tal coisa em Objective-C; ele apenas atribui um objeto a uma variável estática (provavelmente o que você quis dizer, mas só queria ter certeza).
Outra maneira de compartilhar um objeto entre duas ou mais controladores de vista dentro de um controlador de navegação é adicionar uma propriedade para os aninhados controladores de vista, e chamar o método setter antes de navegar. Por exemplo, você pode adicionar uma propriedade como o seguinte:
@property (nonatomic, retain) Book *book;
para uma criança do controlador de vista raiz, e enviá-lo uma mensagem -setBook:
no método -tableView:didSelectRowAtIndexPath:
a visão do controlador de raiz.
Você não está usando o padrão instância compartilhada corretamente. Seu método sharedInstance deve alloc e o init uma nova pessoa (se já não tiver sido feito uma vez) e atribuí-lo à variável sharedInstance estático.
Então, quando você precisa de um ponteiro para a pessoa, você deve usar o método de classe instância compartilhada, não alloc e o init uma nova instância si mesmo.
Tecnicamente, se você estiver indo para um singleton soprado completo, o seu método de alocação não deve permitir que você criar uma nova instância de uma pessoa.
Além disso, eu apenas re-ler o seu código, e me deparei com um pouco de WTF:
Person * ThePerson = [[Person alloc] init];
ThePerson = nil;
O que é aquilo? Isso é um vazamento de memória, ali mesmo.
Todos os seus problemas podem ser resolvidos através da substituição de qualquer e todas as linhas de Person *thePerson = [[Person alloc] init];
com Person *person = [Person sharedInstance];
Seu init é hinky, se você deseja definir o firstName da Pessoa fazê-lo como este
Person *thePerson = [Person sharedInstance];
thePerson.name = @"John Public";
para obter o nome para fora,
NSString *personName = [[Person sharedInstance] name];
Isso irá funcionar em qualquer classe que #imports "Person.h"