iOS持久存储策略

发布于 2024-12-24 22:38:31 字数 446 浏览 3 评论 0原文

我正在开发一个将数据保存到本地文件系统的应用程序。将保存的数据主要是 NSString 和 NSDate。数据不会经常保存,在典型使用情况下新数据可能会输入 10 次。数据当然也应该是可检索的(CRUD)

我应该如何保存这些数据?首先,是否有必要对这些对象进行建模?如果不是,我应该使用属性列表吗?还是SQLLite3?

否则我应该存档班级模型吗?使用SQLLite3?

编辑:我不小心遗漏了有关该应用程序的一些重要信息。实际上,我的应用程序将有 2 个具有聚合关系的数据模型。所以我的第一个数据模型(我们称之为 DataA)将有一个 NSString 和 NSDate 也将引用第二个数据模型(我们称之为 DataB),它本身将由一个 NSString 和一个 NSArray 组成。所以现在事情变得有点复杂了。如果 DataB 中的一个对象被删除,它当然应该不再存在于 DataA 中(但 DataA 的其余部分应该保持不变)

I'm developing an app which will save data to the local file system. The data that will be saved will be mostly NSString and NSDate. The data will not be saved that often, perhaps new data will be entered 10 times at a typical usage. The data should also of course be retrievable (CRUD)

How should I save this data? First of all is it necessary to model these objects? If not should I use property lists? Or SQLLite3?

Else should I archive the class models? Use SQLLite3?

EDIT: I accidentally left out some vital information about the app. Actually my app will be having 2 data models which have an aggregated relationship. So my first data model (lets call it DataA) which will have a NSString and NSDate will also have a reference to the second data model (lets call it DataB) which itself will consist of a NSString and a NSArray. So it gets a little more complicated now. If an object from DataB gets deleted it should of course cease to exist in DataA (but the rest of DataA should be left untouched)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

疾风者 2024-12-31 22:38:31

这种数据的存储和检索似乎非常简单,并且没有任何其他依赖项,例如极其复杂的对象图。

您应该将此数据存储在平面文件或 NSUserDefaults 中。

我将为您提供一个结合使用对象归档和 NSCoding 协议的示例:

@interface ApplicationData <NSCopying, NSCoding> {}

@property (nonatomic, strong) NSDate *someDate;
@property (nonatomic, strong) NSDate *someOtherDate;

@property (nonatomic, copy) NSString *someString;
@property (nonatomic, copy) NSString *someOtherString;

@end

@implementation ApplicationData

@synthesize someDate = _someDate, someOtherDate = _someOtherDate, someString = _someString, someOtherString = _someOtherString;

- (NSArray *)keys {
   static dispatch_once_t once;
   static NSArray *keys = nil;
   dispatch_once(&once, ^{
      keys = [NSArray arrayWithObjects:@"someString", @"someOtherString", @"someDate", @"someOtherDate", nil];
  });
   return keys;
}

- (id) copyWithZone:(NSZone *) zone {
    ApplicationData *data = [[[self class] allocWithZone:zone] init];
    if(data) {
        data.someString = _someString;
        data.someOtherString = _someOtherString;     

        data.someDate = _someDate;
        data.someOtherDate = _someOtherDate;
        //...
    }
    return data;
 }

 - (void) encodeWithCoder:(NSCoder *) coder {
     [super encodeWithCoder:coder];

     NSDictionary *pairs = [self dictionaryWithValuesForKeys:[self keys]];

     for(NSString *key in keys) {
        [coder encodeObject:[pairs objectForKey:key] forKey:key];
     }
  }


  - (id) initWithCoder:(NSCoder *) decoder {
     self = [super initWithCoder:decoder];
     if(self) {
        for(NSString *key in [self keys]) {
           [self setValue:[decoder decodeObjectForKey:key] forKey:key];
        }
     }
     return self;
  }

  @end

然后,在您的应用程序委托中,您可以执行以下操作:

@interface AppDelegate (Persistence)

@property (nonatomic, strong) ApplicationData *data;

- (void)saveApplicationDataToFlatFile;
- (void)loadApplicationDataFromFlatFile;
- (void)saveApplicationDataToUserDefaults;
- (void)loadApplicationDataFromUserDefaults;

@end

@implementation AppDelegate (Persistence) 
@synthesize data;

- (NSString *)_dataFilePath {
   static NSString *path = nil;
   static dispatch_once_t once;
   dispatch_once(&once, ^{
     path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) stringByAppendingPathComponent:@"xAppData.dat"];
   });
   return path;
}

- (void)loadApplicationDataFromUserDefaults {        
   NSData *archivedData = [[NSUserDefaults standardUserDefaults] objectForKey:@"appData"];
   self.data = [NSKeyedUnarchiver unarchiveObjectWithData:archivedData];
}

- (void)saveApplicationDataToUserDefaults {
   NSData *archivedData = [NSKeyedArchiver archivedDataWithRootObject:self.data];
   [[NSUserDefaults standardUserDefaults] setObject:archivedData forKey:@"appData"];
   [[NSUserDefaults standardUserDefaults] synchronize];
}

- (void)loadApplicationDataFromFlatFile {
   NSData *archivedData = [NSData dataWithContentsOfFile:[self _dataFilePath]];
   self.data = [NSKeyedUnarchiver unarchiveObjectWithData:archivedData];
}

- (void)saveApplicationDataToFlatFile {  
   NSData *archivedData = [NSKeyedArchiver archivedDataWithRootObject:self.data];
   [archivedData writeToFile:[self _dataFilePath] atomically:YES];
}

@end

免责声明:I尚未测试此代码。

This kind of data seems to be very simple to store and retrieve and does not have any other dependencies such as a horridly complex object graph.

You should store this data in a flat file or in NSUserDefaults.

I'll give you an example of both, using object archiving with the use of the NSCoding protocol:

@interface ApplicationData <NSCopying, NSCoding> {}

@property (nonatomic, strong) NSDate *someDate;
@property (nonatomic, strong) NSDate *someOtherDate;

@property (nonatomic, copy) NSString *someString;
@property (nonatomic, copy) NSString *someOtherString;

@end

@implementation ApplicationData

@synthesize someDate = _someDate, someOtherDate = _someOtherDate, someString = _someString, someOtherString = _someOtherString;

- (NSArray *)keys {
   static dispatch_once_t once;
   static NSArray *keys = nil;
   dispatch_once(&once, ^{
      keys = [NSArray arrayWithObjects:@"someString", @"someOtherString", @"someDate", @"someOtherDate", nil];
  });
   return keys;
}

- (id) copyWithZone:(NSZone *) zone {
    ApplicationData *data = [[[self class] allocWithZone:zone] init];
    if(data) {
        data.someString = _someString;
        data.someOtherString = _someOtherString;     

        data.someDate = _someDate;
        data.someOtherDate = _someOtherDate;
        //...
    }
    return data;
 }

 - (void) encodeWithCoder:(NSCoder *) coder {
     [super encodeWithCoder:coder];

     NSDictionary *pairs = [self dictionaryWithValuesForKeys:[self keys]];

     for(NSString *key in keys) {
        [coder encodeObject:[pairs objectForKey:key] forKey:key];
     }
  }


  - (id) initWithCoder:(NSCoder *) decoder {
     self = [super initWithCoder:decoder];
     if(self) {
        for(NSString *key in [self keys]) {
           [self setValue:[decoder decodeObjectForKey:key] forKey:key];
        }
     }
     return self;
  }

  @end

Then, say in your application delegate, you can do this:

@interface AppDelegate (Persistence)

@property (nonatomic, strong) ApplicationData *data;

- (void)saveApplicationDataToFlatFile;
- (void)loadApplicationDataFromFlatFile;
- (void)saveApplicationDataToUserDefaults;
- (void)loadApplicationDataFromUserDefaults;

@end

@implementation AppDelegate (Persistence) 
@synthesize data;

- (NSString *)_dataFilePath {
   static NSString *path = nil;
   static dispatch_once_t once;
   dispatch_once(&once, ^{
     path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) stringByAppendingPathComponent:@"xAppData.dat"];
   });
   return path;
}

- (void)loadApplicationDataFromUserDefaults {        
   NSData *archivedData = [[NSUserDefaults standardUserDefaults] objectForKey:@"appData"];
   self.data = [NSKeyedUnarchiver unarchiveObjectWithData:archivedData];
}

- (void)saveApplicationDataToUserDefaults {
   NSData *archivedData = [NSKeyedArchiver archivedDataWithRootObject:self.data];
   [[NSUserDefaults standardUserDefaults] setObject:archivedData forKey:@"appData"];
   [[NSUserDefaults standardUserDefaults] synchronize];
}

- (void)loadApplicationDataFromFlatFile {
   NSData *archivedData = [NSData dataWithContentsOfFile:[self _dataFilePath]];
   self.data = [NSKeyedUnarchiver unarchiveObjectWithData:archivedData];
}

- (void)saveApplicationDataToFlatFile {  
   NSData *archivedData = [NSKeyedArchiver archivedDataWithRootObject:self.data];
   [archivedData writeToFile:[self _dataFilePath] atomically:YES];
}

@end

Disclaimer: I have not tested this code.

吝吻 2024-12-31 22:38:31

如果您只有有限的数据集,NSUserDefault 是不错的选择。
但如果您考虑过滤和获取,那么您应该看看 Core Data 来存储对象。

即使对象图很小,您也将获得缓存对象管理和免费的撤消/重做管理。

NSUserDefault is good choice if you have only a limited set of data.
But if you consider filtering and fetching, then you should have a look to Core Data to store objects.

Even if the object graph is minimal you will gain cached object management and free undo/redo management.

岁月如刀 2024-12-31 22:38:31

我建议您使用NSUserDefaults。这无疑是存储与您的应用程序相关的信息以及任何应用程序相关数据的最佳方法。查看文档!!

I would suggest that you go with NSUserDefaults. It's surely the best approach to store information pertaining to your app and any app related data. Check the documentation !!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文