转载自: http://www.cnblogs.com/yjmyzz/archive/2011/03/03/1969859.html
obj-c中有一类对象:NSArray,NSDictionary,NSString,NSNumber,NSDate,NSData以及它们的可变版本(指NSMutableArray,NSMutableDictionary...这一类) ,都可以方便的将自身的数据以某种格式(比如xml格式)序列化后保存成本地文件。
示例代码:NSArrayTest.h
1
|
#import <Foundation/Foundation.h>
|
2
|
#define FILE_NAME @"/tmp/data.txt"
|
3
|
4
|
@interface
NSArrayTest
:
NSObject
{
|
5
|
}
|
6
|
7
|
-(
void
) Test;
|
8
|
9
|
@end
|
NSArrayTest.m
01
|
#import "NSArrayTest.h"
|
02
|
03
|
@implementation
NSArrayTest
|
04
|
05
|
-(
void
) Test
|
06
|
{
|
07
|
NSArray
*arr = [
NSArray
arrayWithObjects:@
"one"
,@
"two"
,@
"three"
,
nil
];
//注:最后一个要以nil结尾
|
08
|
[arr writeToFile:FILE_NAME atomically:
YES
];
//(序列化为xml格式后)保存文件
|
09
|
|
10
|
NSArray
*arr2 = [
NSArray
arrayWithContentsOfFile:FILE_NAME];
//read file
|
11
|
NSLog
(@
"%@"
,arr2);
|
12
|
13
|
}
|
14
|
15
|
@end
|
运行结果:
2011-03-03 14:20:01.501 pList[1246:a0f] (
one,
two,
three
)
one,
two,
three
)
如果查看/tmp/data.txt,能看到下面的内容:
1
|
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
|
2
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "
http://www.apple.com/DTDs/PropertyList-1.0.dtd
">
|
3
|
<
plist
version
=
"1.0"
>
|
4
|
<
array
>
|
5
|
<
string
>one</
string
>
|
6
|
<
string
>two</
string
>
|
7
|
<
string
>three</
string
>
|
8
|
</
array
>
|
9
|
</
plist
>
|
如果你用来存放数据的类是自己定义的,并不是上面这些预置的对象,那么就要借助
正式协议NSCoding
来实现序列化和反序列化。
比如,我们有一个自己的类Sample.h
01
|
#import <Foundation/Foundation.h>
|
02
|
03
|
@interface
Sample :
NSObject
<
NSCoding
> {
|
04
|
05
|
NSString
* name;
|
06
|
int
magicNumber;
|
07
|
float
shoeSize;
|
08
|
NSMutableArray
*subThingies;
|
09
|
}
|
10
|
11
|
@property
(
copy
)
NSString
* name;
|
12
|
@property
int
magicNumber;
|
13
|
@property
float
shoeSize;
|
14
|
@property
(retain)
NSMutableArray
*subThingies;
|
15
|
16
|
17
|
-(
id
) initWithName:(
NSString
*)n magicNumber:(
int
)m shoeSize:(
float
) ss;
|
18
|
19
|
@end
|
这里我们定义几个不同类型的属性,有字符串,有整数,有浮点数,还有一个可变长的数组对象
Sample.m
01
|
#import "Sample.h"
|
02
|
03
|
@implementation
Sample
|
04
|
05
|
@synthesize
name;
|
06
|
@synthesize
magicNumber;
|
07
|
@synthesize
shoeSize;
|
08
|
@synthesize
subThingies;
|
09
|
10
|
-(
id
) initWithName:(
NSString
*)n magicNumber:(
int
)m shoeSize:(
float
)ss
|
11
|
{
|
12
|
if
(
self
=[
super
init])
|
13
|
{
|
14
|
self
.name = n;
|
15
|
self
.magicNumber = m;
|
16
|
self
.shoeSize = ss;
|
17
|
self
.subThingies = [
NSMutableArray
array];
|
18
|
}
|
19
|
return
(
self
);
|
20
|
}
|
21
|
22
|
-(
void
) dealloc
|
23
|
{
|
24
|
[name release];
|
25
|
[subThingies release];
|
26
|
[
super
dealloc];
|
27
|
}
|
28
|
29
|
//将对象编码(即:序列化)
|
30
|
-(
void
) encodeWithCoder:(
NSCoder
*)aCoder
|
31
|
{
|
32
|
[aCoder encodeObject:name forKey:@
"name"
];
|
33
|
[aCoder encodeInt:magicNumber forKey:@
"magicNumber"
];
|
34
|
[aCoder encodeFloat:shoeSize forKey:@
"shoeSize"
];
|
35
|
[aCoder encodeObject:subThingies forKey:@
"subThingies"
];
|
36
|
}
|
37
|
38
|
//将对象解码(反序列化)
|
39
|
-(
id
) initWithCoder:(
NSCoder
*)aDecoder
|
40
|
{
|
41
|
if
(
self
=[
super
init])
|
42
|
{
|
43
|
self
.name = [aDecoder decodeObjectForKey:@
"name"
];
|
44
|
self
.magicNumber = [aDecoder decodeIntForKey:@
"magicNumber"
];
|
45
|
self
.shoeSize = [aDecoder decodeFloatForKey:@
"shoeSize"
];
|
46
|
self
.subThingies = [aDecoder decodeObjectForKey:@
"subThingies"
];
|
47
|
}
|
48
|
return
(
self
);
|
49
|
|
50
|
}
|
51
|
52
|
53
|
-(
NSString
*) description
|
54
|
{
|
55
|
NSString
*description = [
NSString
stringWithFormat:@
"%@:%d/%.1f %@"
,name,magicNumber,shoeSize,subThingies];
|
56
|
return
(description);
|
57
|
}
|
58
|
59
|
60
|
@end
|
注意其中的:
encodeWithCoder
与
initWithCoder
,这是NSCoding协议中定义的二个方法,用来实现对象的编码与解码。其实现也不复杂,利用的是key-value的经典哈希结构。当然一般在编码中,对于key的名字字符串,建议用define以常量方式事先定义好,以避免开发人员字符串键入错误。
测试一下:
01
|
#import <Foundation/Foundation.h>
|
02
|
#import "Sample.h"
|
03
|
04
|
int
main (
int
argc,
const
char
* argv[]) {
|
05
|
NSAutoreleasePool
* pool = [[
NSAutoreleasePool
alloc] init];
|
06
|
07
|
Sample *s1 = [[Sample alloc] initWithName:@
"thing1"
magicNumber:42 shoeSize:10.5];
|
08
|
[s1.subThingies addObject:@
"1"
];
|
09
|
[s1.subThingies addObject:@
"2"
];
|
10
|
NSLog
(@
"%@"
,s1);
|
11
|
NSData
*data1 = [
NSKeyedArchiver
archivedDataWithRootObject:s1];
//将s1序列化后,保存到NSData中
|
12
|
[s1 release];
|
13
|
[data1 writeToFile:@
"/tmp/data.txt"
atomically:
YES
];
//持久化保存成物理文件
|
14
|
|
15
|
NSData
*data2 = [
NSData
dataWithContentsOfFile:@
"/tmp/data.txt"
];
//读取文件
|
16
|
Sample *s2 = [
NSKeyedUnarchiver
unarchiveObjectWithData:data2];
//反序列化
|
17
|
NSLog
(@
"%@"
,s2);
|
18
|
|
19
|
[pool drain];
|
20
|
return
0;
|
21
|
}
|
运行结果:
2011-03-03 14:36:48.540 pList[1322:a0f] thing1:42/10.5 (
1,
2
)
2011-03-03 14:36:48.548 pList[1322:a0f] thing1:42/10.5 (
1,
2
)
查看/tmp/data.txt,能看到以下内容:
由于经过了编码,里面的内容没有象前面的NSArray那样可读性强。
作者:
菩提树下的杨过
出处: http://yjmyzz.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
出处: http://yjmyzz.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。