tanpuer
tanpuer

Reputation: 59

On iOS, AsyncStorage is backed by native code that stores small values in a serialized dictionary and larger values in separate files

The title is the introduction in the official website. But I have a question. Can anyone explain "small" and "larger"? And in programming, if i have a model which contains 20 objects. Should I save the model in 20 separate key-value pairs or just in one pair? Which one is more efficient?

Upvotes: 0

Views: 318

Answers (1)

martinarroyo
martinarroyo

Reputation: 9701

I just dug into the source code of RCTAsyncLocalStorage, particularly this block:

- (NSDictionary *)_writeEntry:(NSArray<NSString *> *)entry changedManifest:(BOOL *)changedManifest
{
  if (entry.count != 2) {
    return RCTMakeAndLogError(@"Entries must be arrays of the form [key: string, value: string], got: ", entry, nil);
  }
  NSString *key = entry[0];
  NSDictionary *errorOut = RCTErrorForKey(key);
  if (errorOut) {
    return errorOut;
  }
  NSString *value = entry[1];
  NSString *filePath = [self _filePathForKey:key];
  NSError *error;
  if (value.length <= RCTInlineValueThreshold) {
    if (_manifest[key] == (id)kCFNull) {
      // If the value already existed but wasn't inlined, remove the old file.
      [[NSFileManager defaultManager] removeItemAtPath:filePath error:nil];
      [RCTGetCache() removeObjectForKey:key];
    }
    *changedManifest = YES;
    _manifest[key] = value;
    return nil;
  }

[value writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:&error];

Where RCTInlineValueThreshold is defined a few lines before (source) as:

static const NSUInteger RCTInlineValueThreshold = 1024;

So values (your object will be serialized as a string) smaller or equal than 1024 will be stored in a serialized dictionary, and bigger objects in a separate file.

As for spreading an object into n key-value pairs, it might affect performance since you will have to do n queries to the storage (involving communication from JS to Native and viceversa n times, which is a costly operation) instead of just one call, but it might also depend on the frequency the data is queried and how (for instance if 1 object is queried often whereas the rest are not, it might make sense to split them in order to avoid serialization and deserialization of long strings).

Upvotes: 1

Related Questions