Dans mon application, je veux enregistrer les paramètres utilisateur dans un fichier plist pour chaque utilisateur se connecte, j'écris one class called CCUserSettings
qui a presque la même interface que NSUserDefaults
et il lit et écrit un fichier plist lié à l'ID de l'utilisateur actuel. Cela fonctionne mais a de mauvaises performances. Chaque fois que l'utilisateur appelle [[CCUserSettings sharedUserSettings] synchronize]
, j'écris un NSMutableDictionary
(qui garde les paramètres utilisateur) dans un fichier plist, le code ci-dessous montre synchronize
de CCUserSettings
en omettant quelques détails triviaux.Comment `NSUserDefaults synchronize` peut-il fonctionner aussi vite?
- (BOOL)synchronize {
BOOL r = [_settings writeToFile:_filePath atomically:YES];
return r;
}
Je suppose que NSUserDefaults
devrait écrire dans des fichiers lorsque nous appelons [[NSUserDefaults standardUserDefaults] synchronize]
, mais il fonctionne très vite, j'écris un demo pour tester, la partie clé est ci-dessous, exécution 1000 fois [[NSUserDefaults standardUserDefaults] synchronize]
et [[CCUserSettings sharedUserSettings] synchronize]
sur mon iPhone6, le résultat est de 0.45 secondes contre 9.16 secondes.
NSDate *begin = [NSDate date];
for (NSInteger i = 0; i < 1000; ++i) {
[[NSUserDefaults standardUserDefaults] setBool:(i%2==1) forKey:@"key"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
NSDate *end = [NSDate date];
NSLog(@"synchronize seconds:%f", [end timeIntervalSinceDate:begin]);
[[CCUserSettings sharedUserSettings] loadUserSettingsWithUserId:@"1000"];
NSDate *begin = [NSDate date];
for (NSInteger i = 0; i < 1000; ++i) {
[[CCUserSettings sharedUserSettings] setBool:(i%2==1) forKey:@"_boolKey"];
[[CCUserSettings sharedUserSettings] synchronize];
}
NSDate *end = [NSDate date];
NSLog(@"CCUserSettings modified synchronize seconds:%f", [end timeIntervalSinceDate:begin]);
Comme le montre le résultat, NSUserDefaults
est presque 20 fois plus rapide que mon CCUserSettings
. Maintenant, je commence à me demander si "NSUserDefaults écrit vraiment dans les fichiers plist à chaque fois que nous appelons la méthode synchronize
?", Mais si ce n'est pas le cas, comment peut-il garantir que les données sont réécrites dans le fichier? être tué à tout moment)?
Ces jours je viens avec une idée pour améliorer mon CCUserSettings
, il est mmap
Memory-mapped I/O. Je peux mapper une mémoire virtuelle dans un fichier et chaque fois que l'utilisateur appelle synchronize
, je crée une méthode NSData
avec NSPropertyListSerialization dataWithPropertyList:format:options:error:
et copier les données dans cette mémoire, le système d'exploitation va écrire la mémoire dans le fichier lorsque le processus se termine. Mais je ne peux pas obtenir une bonne performance parce que la taille du fichier n'est pas fixe, chaque fois que la longueur des données augmente, je dois mmap
une mémoire virtuelle, je crois que l'opération prend du temps.
Désolé pour mes détails redondants, je veux juste savoir comment NSUserDefaults
fonctionne pour atteindre de si bonnes performances, ou quelqu'un peut-il avoir de bons conseils pour améliorer mon CCUserSettings
?
Voici un bel article sur les 'NSUserDefaults': http://dscoder.com /defaults.html. Son auteur est un ingénieur chez Apple, donc c'est assez sûr de supposer qu'il sait de quoi il parle :) – Losiowaty
@Losiowaty Merci pour votre lien, mais je pense qu'il parle de la mise en œuvre en mac ox, car il dit "Définir une valeur sera (finalement, il est asynchrone et se produit quelque temps plus tard dans un autre processus) écrire tout le plist sur le disque, peu importe la taille du changement. " Si vous modifiez NSUserDefaults et que vous tuez votre application sans 'synchronize', les paramètres ne seront pas écrits dans le fichier, donc je ne pense pas qu'il existe un autre processus qui écrit le fichier dans iOS. – KudoCC
Si vous modifiez NSUserDefaults et que vous tuez l'application, vous devrez être * très * rapide sur le bouton kill pour perdre des données. Quelques millisecondes environ. Cela a changé dans iOS 8; avant cela, il était beaucoup plus facile de perdre des données de cette façon. –