美文网首页
iOS 自定义 model 数据持久化

iOS 自定义 model 数据持久化

作者: 摘心 | 来源:发表于2018-12-04 14:06 被阅读17次
自定义model 无法直接存入沙盒,需要先将 model 转成 NSData,然后将 data 存入沙盒。读取的时候也是读到 NSData,然后将 data 转成 model。所以自定义 model 必须遵循 NSCoding 协议。

1.model 签NSCoding 协议,并实现协议方

- (void)encodeWithCoder:(nonnull NSCoder *)aCoder {
    [aCoder encodeObject:_name forKey:@"name"];
    [aCoder encodeObject:@(_num) forKey:@"num"];
    [aCoder encodeObject:@(_sex) forKey:@"sex"];
}

- (nullable instancetype)initWithCoder:(nonnull NSCoder *)aDecoder {
  self = [super init];
  if (self) {
    _name = [aDecoder decodeObjectForKey:@"name"];
    _num = [[aDecoder decodeObjectForKey:@"num"] intValue];
    _sex = [[aDecoder decodeObjectForKey:@"sex"] intValue];
  }
  return self;
}

2.自定义读取、保存方法

+(CustomModel *)createCustomModel
{
  id modelId = [[NSUserDefaults standardUserDefaults] objectForKey:KSaveCustomModelKey];
  if (modelId && [modelId isKindOfClass:[NSData class]]) {
    id model = [NSKeyedUnarchiver unarchiveObjectWithData:(NSData *)modelId];
    if (model && [model isKindOfClass:[CustomModel class]]) {
      return (CustomModel *)model;
    }
  }
  return [[CustomModel alloc] init];
}

- (void)saveCustomModel
{
  NSData *data = [NSKeyedArchiver archivedDataWithRootObject:self];
  if (data) {
    [[NSUserDefaults standardUserDefaults] setObject:data forKey:KSaveCustomModelKey];
    [[NSUserDefaults standardUserDefaults] synchronize];
  }
}

通过以上方法就可以实现自定义 model 的数据持久化,但是当 model 的属性太多就会导致写好多重复代码,下面我们可以使用 runtime 做一下简单优化。

3.优化

// 使用 runtime 遍历 model 的所有属性
+ (void)goThroughAllProperty:(id)object propertyBlock:(void(^)(NSString *propertyName))propertyBlcok {
  u_int count;
  objc_property_t *propertyList = class_copyPropertyList([object class], &count);
  for (int i = 0; i < count; i++) {
    const char *propertyChar = property_getName(propertyList[i]);
    NSString *propertyName = [NSString stringWithUTF8String:propertyChar];
    if (propertyBlcok) {
      propertyBlcok(propertyName);
    }
  }
  free(propertyList);
}

#pragma mark NSCoding protocol
- (void)encodeWithCoder:(nonnull NSCoder *)aCoder {
  __weak typeof(self) weakself = self;
  [[self class] goThroughAllProperty:self propertyBlock:^(NSString *propertyName) {
    id value = [weakself valueForKey:propertyName];
    [aCoder encodeObject:value forKey:propertyName];
  }];
}

- (nullable instancetype)initWithCoder:(nonnull NSCoder *)aDecoder {
  self = [super init];
  if (self) {
    __weak typeof(self) weakself = self;
    [[self class] goThroughAllProperty:self propertyBlock:^(NSString *propertyName) {
      id value = [aDecoder decodeObjectForKey:propertyName];
      [weakself setValue:value forKey:propertyName];
    }];
  }
  return self;
}

这样写可以节省很多不必要的重复,并且可以避免出错和数据丢失。

相关文章

  • iOS本地数据持久化

    iOS本地数据持久化 iOS本地数据持久化

  • iOS 自定义 model 数据持久化

    1.model 签NSCoding 协议,并实现协议方 2.自定义读取、保存方法 通过以上方法就可以实现自定义 m...

  • iOS本地数据持久化

    转载自:CocoaChina - iOS本地数据持久化 本文内容:iOS本地数据持久化的几种类型iOS本地数据持久...

  • iOS 数据持久化方案-Realm的使用

    iOS 数据持久化方案-Realm的使用 iOS 数据持久化方案-Realm的使用

  • iOS持久化存储

    iOS有以下几种数据持久化方式 NSUserDefault (无法保存自定义对象) plist表 (无法保存自定义...

  • iOS本地数据持久化

    本文内容: iOS本地数据持久化的几种类型 iOS本地数据持久化几种类型的应用场景及使用 一.iOS本地数据持久化...

  • iOS 数据持久化

    iOS本地数据持久化 本文内容:iOS本地数据持久化的几种类型iOS本地数据持久化几种类型的应用场景及使用 一.i...

  • iOS本地数据持久化

    本文内容:iOS本地数据持久化的几种类型iOS本地数据持久化几种类型的应用场景及使用 一,iOS本地数据持久化的类...

  • ios数据持久化

    本文内容:iOS本地数据持久化的几种类型iOS本地数据持久化几种类型的应用场景及使用 一.iOS本地数据持久化的类...

  • iOS Realm数据持久化--Realm集合分页(四)

    iOS Realm数据持久化--Realm基础知识 (一)iOS Realm数据持久化--数据分页与复用原理 (二...

网友评论

      本文标题:iOS 自定义 model 数据持久化

      本文链接:https://www.haomeiwen.com/subject/niumcqtx.html