web-dev-qa-db-fra.com

Existe-t-il une limite au stockage de valeurs dans NSUserDefaults?

Je suis nouveau dans le développement iPhone et le Objective C. J'ai utilisé NSUserDefaults pour stocker certaines valeurs dans mon application . Mais je ne sais pas s'il existe une limite quelconque pour le stockage de valeurs dans NSUserDefaults. aidez-moi à le savoir.

Merci d'avance.

59
Johnykutty

Tant qu'il y a suffisamment d'espace sur l'iPhone/iPad, vous pouvez stocker les valeurs NSUserDefault. Toutes ces valeurs sont stockées dans un fichier .plist, et ce fichier est très petit, le plus souvent inférieur à 1 ko (sauf si vous stockez beaucoup de données).

46
user914372

Les types que vous pouvez stocker sont limités: ils doivent tous être des objets de liste de propriétés, à savoir NSString, NSNumber, NSData, NSArray et NSDictionary. De plus, vous ne pouvez stocker NSArray et NSDictionary que si les valeurs sont également des objets de liste de propriétés; de plus, toutes les clés de la variable NSDictionary doivent être des chaînes.

Notez qu'un objet comme UIColor ne figure pas dans la liste ci-dessus. Ainsi, si vous souhaitez stocker une couleur dans la base de données par défaut, vous devez d'abord la convertir en chaîne ou en objet de données, puis la reconvertir lorsque vous lisez les valeurs par défaut.

En ce qui concerne les limites de taille, il n'y en a aucune qui soit documentée, mais notez que toutes les données seront stockées sous la forme d'un fichier de liste de propriétés. Le fichier entier est lu et écrit comme un tout. Par conséquent, si vous utilisez NSUserDefaults pour stocker une grande quantité de données qui ne changent que partiellement, vous perdrez beaucoup de temps à faire des E/S inutiles.

42
benzado

Tout le monde a répondu à la question directe de "Y a-t-il une limite?" Cependant, j'ai trouvé que ce fil cherchait vraiment à comprendre "combien coûte trop à stocker dans UserDefaults?"

Si vous recherchez cette réponse, voici un utile thread . Les réponses qui m'ont été utiles ont été d'aller dans votre fichier de projet et de regarder la taille du fichier Plist:

5 objets, c'est presque rien. Ça ira!


Sur ma machine, j'ai environ 28 Mo de données dans les paramètres par défaut de l'utilisateur. Cela ne pose aucun problème.


Si vous connaissez bien les baies de disques, je suppose que les performances commencent à décroître rapidement lorsque vous atteignez 1000, en fonction de la taille de l’élément. Par conséquent, dans un programme, je n’aurais pas de problème à stocker quelques centaines d’éléments. Cela dit, je commencerais probablement par utiliser une base de données sqlite3 ou coredata, le plus tôt possible si j’étais vous-même.

Important à retenir:

Ce qui précède a dissipé mes inquiétudes quant au fait que mon nombre croissant de défauts (environ 20 à 25 maintenant) poserait des problèmes. J'utilise déjà CoreData, donc je réfléchissais au type d'utilisation à utiliser, car mon nombre de préférences/personnalisations utilisateur autorisées augmente depuis longtemps. Donc, je vais rester avec les valeurs par défaut de l'utilisateur.

Cependant, comme d'autres réponses l'ont souligné, le fichier sera lu et écrit dans son ensemble. Donc, lire 20 dictionnaires de clés/chaînes et 5 dictionnaires de clés/booléens juste pour récupérer une chaîne ... pas exactement idéal. Néanmoins, si cela ne nuit pas aux performances et vous épargne une tonne de code, pourquoi pas?

8
Dave G

Il n'y a pas de limite pour stocker des valeurs dans NSUserDefaults.

4
Manmay

À partir des codes du SDK iOS et document officiel Apple apparenté. .

extension UserDefaults {


    /*!
     NSUserDefaultsSizeLimitExceededNotification is posted on the main queue when more data is stored in user defaults than is allowed. Currently there is no limit for local user defaults except on tvOS, where a warning notification will be posted at 512kB, and the process terminated at 1MB. For ubiquitous defaults, the limit depends on the logged in iCloud user.
     */
    @available(iOS 9.3, *)
    public class let sizeLimitExceededNotification: NSNotification.Name


    // ....
 }   


Résumé

  1. Actuellement, il n'y a pas de limite pour les utilisateurs par défaut 
  2. Sur tvOS, une notification d'avertissement sera publiée à 512 Ko et le processus terminé à 1 Mo.
  3. Pour les valeurs par défaut omniprésentes, la limite dépend de l'utilisateur iCloud connecté.
3
AechoLiu

Comme beaucoup l'ont déjà mentionné: je ne connais aucune limitation SIZE (sauf la mémoire physique) permettant de stocker des données dans une liste .plist (par exemple, UserDefaults). Donc, ce n’est pas une question de COMBIEN.

La vraie question devrait être de savoir combien de fois vous écrivez de nouvelles valeurs/modifications ... Et ceci est lié à l'épuisement de la batterie qui en résultera.

IOS n'a aucune chance d'éviter une écriture physique sur "disque" si une seule valeur était modifiée, uniquement pour préserver l'intégrité des données. En ce qui concerne UserDefaults, le fichier entier est réécrit sur le disque. 

Cela met le "disque" sous tension et le maintient allumé plus longtemps tout en empêchant IOS de passer à l'état d'alimentation réduite.

De "Guide d'efficacité énergétique pour les applications iOS":

Réduisez les écritures de données. Écrivez dans les fichiers uniquement lorsque leur contenu a changé et regroupez les modifications en une seule écriture chaque fois que cela est possible.Évitez d’écrire un fichier entier si quelques octets seulement ont été modifiés.Si vous modifiez fréquemment de petites portions de gros fichiers, envisagez d'utiliser une base de données pour stocker les données.

Les READs ne posent aucun problème, car toutes les valeurs sont mises en cache en mémoire.

2
Hardy_Germany

Pour autant que je sache, il n'y a pas de limite de stockage dans NSUserdefaults.

2
Tendulkar

Quelle que soit la taille de fichier maximale autorisée sur le lecteur. Vous pouvez utiliser ce morceau de code pour le vérifier!

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *myKey = @"key";
int sizeOfFile = 1024; // Fill in proper file size here
NSData myObject;
NSString *someFilePath = @"PathToYourFileHere";

for(int i = 1; i < 9999999999999999; i++)
{
  myObject = [NSData dataWithContentsOfFile:someFilePath];
  [defaults setObject:myObject forKey:[NSString stringWithFormat:@"%@%i", myKey, i]];
  NSLog(@"Iteration: %i, TotalWritten: %i", i, i * sizeOfFile);
}
0
Esqarrouth