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.

questionAnswers(2)

yourAnswerToTheQuestion