O iOS 10 com XCode 8 GM fez com que NSUserDefaults intermitentemente não funcionasse
NOTA: Tenho visto muitas outras postagens no Stack Overflow sobreNSUserDefaults
sendo renomeado paraUserDefaults
no Swift ou não está trabalhando no simulador até uma reinicialização. Esta não é uma duplicata de qualquer maneira. Muitas das perguntas contra as quais SOs estão sendo marcadas são de 4 anos atrás. Minha pergunta é específica para o iOS 10 deste ano, pois sempre funcionou em versões mais antigas. Já mencionei na minha pergunta que minha pergunta não é uma duplicata dessas perguntas, pois eram bugs do simulador rapidamente e meu problema está no bug C do objetivo do dispositivo.Por favor, leia as perguntas antes de marcar como duplicado
Meu problema é diferente, pois sou capaz de reproduzir isso no objetivo C e no próprio dispositivo físico.
Eu criei um novo projeto do zero para este teste. Eu coloquei esse código noviewDidLoad
de um controlador de exibição:
if (![[NSUserDefaults standardUserDefaults] valueForKey:@"checkIfInitialized"]){
NSLog(@"setting checkIfInitialized as not exist");
[[NSUserDefaults standardUserDefaults] setValue:@"test" forKey:@"checkIfInitialized"];
[[NSUserDefaults standardUserDefaults] synchronize];
self.view.backgroundColor=[UIColor redColor];
self.mylabel.text=@"NSUserDefaults was NOT there, try running again";
} else {
NSLog(@"checkIfInitialized exists already");
self.view.backgroundColor=[UIColor blueColor];
self.mylabel.text=@"NSUserDefaults was already there this time, try running again";
}
Agora, se eu executar o aplicativo cerca de 10 vezes, algumas vezes ele encontrará ocheckIfInitialized
e às vezes não. Não há um número exato de quantas vezes ele falha, pois pode funcionar 3 vezes e depois falha nas próximas 2 vezes e depois funciona 4 vezes e falha uma vez e assim por diante.
Agora, algo que eu notei (mas não tenho 100% de certeza) de que o problema só parece acontecer quando estou testando o Xcode. Se eu executar iniciando o aplicativo clicando no ícone do aplicativo no dispositivo sem o Xcode, ele parece funcionar bem, mas não tenho 100% de certeza.
Notei que este erro ocorre algumas vezes:
[User Defaults] Failed to write value for key checkIfInitialized in CFPrefsPlistSource<0x1700f7200> (Domain: com.xxxx.appname, User: kCFPreferencesCurrentUser, ByHost: No, Container: (null)): Path not accessible, switching to read-only
Eu tenho esse projeto muito simples na minha caixa de depósito se você quiser testá-lo. Eu sugeriria testar cerca de 10 a 15 vezes para reproduzir esse problema.
https://www.dropbox.com/s/j7vbgl6e15s57ix/nsuserdefaultbug.zip?dl=0
Isso funciona completamente bem no iOS 9, então definitivamente algo a ver com o iOS 10.
EDITAR Bug registrado: 28287988
Resposta da equipe apple DTS:
Primeiro, você deve determinar primeiro se standardUserDefaults ou valueForKey está falhando. Meu palpite é que "standardUserDefaults" está retornando NULL e, se for esse o caso, é algo que você deve proteger em geral. Notavelmente, standardUserDefaults retornará NULL se o arquivo de preferências estiver criptografado no ambiente em que o aplicativo está sendo executado no momento (por exemplo, as preferências estão definidas como "NSFileProtectionComplete" e o aplicativo está sendo executado em segundo plano). Isso não deve ser um problema para aplicativos padrão apenas em primeiro plano, mas é algo para estar ciente de qualquer maneira.
É muito provável que o Xcode esteja realmente induzindo o problema aqui. O Xcode complica bastante o ambiente de inicialização do aplicativo de uma maneira MUITO diferente do lançamento padrão do aplicativo. Meu palpite é que isso está basicamente sendo disparado pelo tempo do Xcode, induzindo uma situação esperada durante o lançamento do aplicativo, mas se você quiser um teste mais formal disso, tente definir um único ponto de interrupção no applicationDidFinishLaunching e continue no depurador assim que você o acertar . Meu palpite é apenas acrescentar que isso interrompe o tempo suficiente para impedir que o problema aconteça. Tipo de. É o iOS 10 apenas no sentido de que o iOS 9 nunca imprimirá essa mensagem de log, mas isso ocorre porque a mensagem de log foi adicionada no iOS 10. O código em si é semelhante o suficiente ao iOS 9.3 e suspeito que seja exatamente o mesmo comportamento (pelo menos em teoria) possível no iOS 9.