基础数据持久化指南
立即解锁
发布时间: 2025-08-24 01:11:21 阅读量: 1 订阅数: 7 

### 基础数据持久化指南
在开发应用程序时,数据持久化是一个关键的需求。我们需要确保应用程序的数据能够在设备重启或应用关闭后仍然存在。本文将介绍几种常见的数据持久化方法,包括归档模型对象、使用属性列表以及 iOS 内置的 SQLite3 数据库。
#### 归档模型对象
在 Cocoa 开发中,归档是一种序列化的方式,它允许我们将复杂的对象写入文件并在需要时读取回来。只要类中的每个属性是标量类型(如 int 或 float),或者是符合 NSCoding 协议的类的实例,就可以完全归档该对象。
1. **遵循 NSCoding 协议**
NSCoding 协议声明了两个必需的方法:
- `encodeWithCoder:`:将对象编码到归档中。
- `initWithCoder:`:通过解码归档创建新对象。
以下是一个编码对象的示例方法:
```objc
- (void)encodeWithCoder:(NSCoder *)encoder
{
[encoder encodeObject:foo forKey:kFooKey];
[encoder encodeObject:bar forKey:kBarKey];
[encoder encodeInt:someInt forKey:kSomeIntKey];
[encoder encodeFloat:someFloat forKey:kSomeFloatKey];
}
```
如果子类化的类也符合 NSCoding 协议,需要调用父类的 `encodeWithCoder:` 方法:
```objc
- (void)encodeWithCoder:(NSCoder *)encoder
{
[super encodeWithCoder:encoder];
[encoder encodeObject:foo forKey:kFooKey];
[encoder encodeObject:bar forKey:kBarKey];
[encoder encodeInt:someInt forKey:kSomeIntKey];
[encoder encodeFloat:someFloat forKey:kSomeFloatKey];
}
```
实现 `initWithCoder:` 方法稍微复杂一些。如果直接子类化 NSObject 或子类化的类不符合 NSCoding 协议,方法如下:
```objc
- (id)initWithCoder:(NSCoder *)decoder
{
if (self = [super init]) {
foo = [decoder decodeObjectForKey:kFooKey];
bar = [decoder decodeObjectForKey:kBarKey];
someInt = [decoder decodeIntForKey:kSomeIntKey];
someFloat = [decoder decodeFloatForKey:kAgeKey];
}
return self;
}
```
如果父类也符合 NSCoding 协议,需要调用父类的 `initWithCoder:` 方法:
```objc
- (id)initWithCoder:(NSCoder *)decoder
{
if (self = [super initWithCoder:decoder]) {
foo = [decoder decodeObjectForKey:kFooKey];
bar = [decoder decodeObjectForKey:kBarKey];
someInt = [decoder decodeIntForKey:kSomeIntKey];
someFloat = [decoder decodeFloatForKey:kAgeKey];
}
return self;
}
```
2. **实现 NSCopying 协议**
对于数据模型对象,遵循 NSCopying 协议是一个很好的做法。NSCopying 协议有一个方法 `copyWithZone:`,允许对象被复制。
```objc
- (id)copyWithZone:(NSZone *)zone
{
MyClass *copy = [[[self class] allocWithZone:zone] init];
copy.foo = [self.foo copyWithZone:zone];
copy.bar = [self.bar copyWithZone:zone];
copy.someInt = self.someInt;
copy.someFloat = self.someFloat;
return copy;
}
```
不需要过于担心 `NSZone` 参数,现在几乎不需要手动管理内存区域。
3. **归档和解档数据对象**
创建符合 NSCoding 协议的对象的归档相对简单:
```objc
NSMutableData *data = [[NSMutableData alloc] init];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc]
initForWritingWithMutableData:data];
[archiver encodeObject:myObject forKey:@"keyValueString"];
[archiver finishEncoding];
BOOL success = [data writeToFile:@"/path/to/archive" atomically:YES];
```
从归档中恢复对象的过程类似:
```objc
NSData *data = [[NSData alloc] initWithContentsOfFile:@"/path/to/archive"];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc]
initForReadingWithData:data];
self.object = [unarchiver decodeObjectForKey:@"keyValueString"];
[unarchiver finishDecoding];
```
#### 归档应用示例
我们将重新实现一个应用程序,使其使用归档而不是属性列表。
1. **实现 BIDFourLines 类**
首先,创建一个名为 BIDFourLines 的类,它将作为我们的数据模型。
```objc
// BIDFourLines.h
#import <Foundation/Foundation.h>
@interface BIDFourLines : NSObject <NSCoding, NSCopying>
@property (copy, nonatomi
```
0
0
复制全文
相关推荐










