转载自【黑米GameDev街区】 原文链接: http://www.himigame.com/iphone-cocos2d/513.html
OK,今天Himi介绍游戏存储这一块,在Android游戏开发中Himi介绍了好几种保存的方式和形式,那么在iOS中也有几种方式,一般常用的有以下四种形式:
1. NSKeyedArchiver(加密形式)
2. NSUserDefaults
3. Write写入方式
4. SQLite3
这里Himi就不再介绍SQlite数据库了,Android游戏存储中我也介绍过SQLite如何保存数据,但是由于这一块很多童鞋没有接触过数据库相关知识,所以即使讲了也没作用,那么对于数据数据库的童鞋们可以参考其他博文或书籍进行学习;
首先介绍第一种保存方式:NSKeyedArchiver
代码很简单就不多解释了直接上代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
//=================NSKeyedArchiver========================
NSString *
saveStr1
=
@
"我是"
;
NSString *
saveStr2
=
@
"数据"
;
NSArray *
array
=
[
NSArray
arrayWithObjects
:
saveStr1
,
saveStr2
,
nil
]
;
//----Save
//这一句是将路径和文件名合成文件完整路径
NSString *
Path
=
[
NSSearchPathForDirectoriesInDomains
(
NSDocumentDirectory
,
NSUserDomainMask
,
YES
)
objectAtIndex
:
0
]
;
NSString *
filename
=
[
Path
stringByAppendingPathComponent
:
@
"saveDatatest"
]
;
[
NSKeyedArchiver
archiveRootObject
:
array
toFile
:
filename
]
;
//用于测试是否已经保存了数据
saveStr1
=
@
"hhhhhhiiii"
;
saveStr2
=
@
"mmmmmmiiii"
;
//----Load
array
=
[
NSKeyedUnarchiver
unarchiveObjectWithFile
:
filename
]
;
saveStr1
=
[
array
objectAtIndex
:
0
]
;
saveStr2
=
[
array
objectAtIndex
:
1
]
;
CCLOG
(
@
"str:%@"
,
saveStr1
)
;
CCLOG
(
@
"astr:%@"
,
saveStr2
)
;
|
第二种保存方式:NSUserDefaults
代码很简单就不多解释了直接上代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
//=================NSUserDefaults========================
NSString *
saveStr1
=
@
"我是"
;
NSString *
saveStr2
=
@
"数据"
;
NSArray *
array
=
[
NSArray
arrayWithObjects
:
saveStr1
,
saveStr2
,
nil
]
;
//Save
NSUserDefaults *
saveDefaults
=
[
NSUserDefaults
standardUserDefaults
]
;
[
saveDefaults
setObject
:
array
forKey
:
@
"SaveKey"
]
;
//用于测试是否已经保存了数据
saveStr1
=
@
"hhhhhhiiii"
;
saveStr2
=
@
"mmmmmmiiii"
;
//---Load
array
=
[
saveDefaults
objectForKey
:
@
"SaveKey"
]
;
saveStr1
=
[
array
objectAtIndex
:
0
]
;
saveStr2
=
[
array
objectAtIndex
:
1
]
;
CCLOG
(
@
"str:%@"
,
saveStr1
)
;
CCLOG
(
@
"astr:%@"
,
saveStr2
)
;
|
第三种保存方式:Write写入方式
代码很简单就不多解释了直接上代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
//=================Write写入方式========================
NSString *
saveStr1
=
@
"我是"
;
NSString *
saveStr2
=
@
"数据"
;
NSArray *
array
=
[
NSArray
arrayWithObjects
:
saveStr1
,
saveStr2
,
nil
]
;
//----Save
NSArray *
paths
=
NSSearchPathForDirectoriesInDomains
(
NSDocumentDirectory
,
NSUserDomainMask
,
YES
)
;
NSString *
documentsDirectory
=
[
paths
objectAtIndex
:
0
]
;
if
(
!
documentsDirectory
)
{
NSLog
(
@
"没找到"
)
;
}
NSMutableArray *
saveDataArray
=
nil
;
NSString *
appFile
=
[
documentsDirectory
stringByAppendingPathComponent
:
@
"Savedatas.plist"
]
;
[
[
NSArray
arrayWithObjects
:
array
,
nil
]
writeToFile
:
appFile
atomically
:
NO
]
;
//用于测试是否已经保存了数据
saveStr1
=
@
"hhhhhhiiii"
;
saveStr2
=
@
"mmmmmmiiii"
;
//----Load
if
(
[
[
NSFileManager
defaultManager
]
fileExistsAtPath
:
appFile
]
)
{
saveDataArray
=
[
NSMutableArray
arrayWithContentsOfFile
:
appFile
]
;
}
else
{
saveDataArray
=
[
NSMutableArray
arrayWithContentsOfFile
:
[
[
NSBundle
mainBundle
]
pathForResource
:
@
"Savedatas"
ofType
:
@
"plist"
]
]
;
}
NSArray *
strArray
=
[
saveDataArray
objectAtIndex
:
0
]
;
saveStr1
=
[
strArray
objectAtIndex
:
0
]
;
saveStr2
=
[
strArray
objectAtIndex
:
1
]
;
CCLOG
(
@
"str:%@"
,
saveStr1
)
;
CCLOG
(
@
"astr:%@"
,
saveStr2
)
;
|
不论哪种形式代码都很容易理解,那么以上三种保存方式代码中都带有如下两行代码;
1
2
|
saveStr1
=
@
"hhhhhhiiii"
;
saveStr2
=
@
"mmmmmmiiii"
;
|
我已经注释上了,为了验证是否保存数据成功,如果没有保存成功,最后打印的肯定就是hhhhhhiiiiiiiii,mmmmiiiii啦~正常保存的话如下图控制台信息:
由于本章介绍过于简单,那么下面Himi对Write写入方式保存数据和读取数据封装了两个方法这里放出,给童鞋们行个方便:(其他两种大家封装起来风容易了,这里就不写了);
封装的函数如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
//保存游戏数据
//参数介绍:
// (NSMutableArray *)data :保存的数据
// (NSString *)fileName :存储的文件名
-
(
BOOL
)
saveGameData
:
(
NSMutableArray *
)
data
saveFileName
:
(
NSString *
)
fileName
{
NSArray *
paths
=
NSSearchPathForDirectoriesInDomains
(
NSDocumentDirectory
,
NSUserDomainMask
,
YES
)
;
NSString *
documentsDirectory
=
[
paths
objectAtIndex
:
0
]
;
if
(
!
documentsDirectory
)
{
NSLog
(
@
"Documents directory not found!"
)
;
return
NO
;
}
NSString *
appFile
=
[
documentsDirectory
stringByAppendingPathComponent
:
fileName
]
;
return
(
[
data
writeToFile
:
appFile
atomically
:
YES
]
)
;
}
//读取游戏数据
//参数介绍:
// (NSString *)fileName :需要读取数据的文件名
-
(
id
)
loadGameData
:
(
NSString *
)
fileName
{
NSArray *
paths
=
NSSearchPathForDirectoriesInDomains
(
NSDocumentDirectory
,
NSUserDomainMask
,
YES
)
;
NSString *
documentsDirectory
=
[
paths
objectAtIndex
:
0
]
;
NSString *
appFile
=
[
documentsDirectory
stringByAppendingPathComponent
:
fileName
]
;
NSMutableArray *
myData
=
[
[
[
NSMutableArray
alloc
]
initWithContentsOfFile
:
appFile
]
autorelease
]
;
return
myData
;
}
|
使用代码如下:
1
2
3
4
5
6
|
NSString *
saveStr1
=
@
"测试保存读取"
;
NSString *
saveStr2
=
@
"两个函数"
;
NSMutableArray *
array
=
[
NSMutableArray
arrayWithObjects
:
saveStr1
,
saveStr2
,
nil
]
;
[
self
saveGameData
:
array
saveFileName
:
@
"Himi"
]
;
NSMutableArray*
temp
=
(
NSMutableArray*
)
[
self
loadGameData
:
@
"Himi"
]
;
CCLOG
(
@
"%@--%@"
,
[
temp
objectAtIndex
:
0
]
,
[
temp
objectAtIndex
:
1
]
)
;
|
运行效果截图如下:
这里Himi要提醒大家两点细节也是需要注意的地方:
1.对于取出数据的时候需要注意,例如如下代码:
1
2
3
|
NSUserDefaults *
saveDefaults
=
[
NSUserDefaults
standardUserDefaults
]
;
NSMutableArray *
arraySaveData
=
[
saveDefaults
objectForKey
:
@
"OhSaveData"
]
;
//NSMutableArray *arraySaveData=[NSMutableArray arrayWithArray:[saveDefaults objectForKey:@"OhSaveData"]];
|
第二句代码是通过一个文件名获取你存储的数据,返回数据数组,但是!一定要注意这里返回的数据数组是不可修改的!及时你将读取的数据赋给一个可修改的数组中也一样无法修改其中的数据,所以如果你想将取出的数据进行修改那么这里需要要使用第三行代码来获取,这里Himi将获取出的数据数组首先copy给了可修改数组中,那么此时你的可修改数组就可以正常修改了!
2.修改已经的存储文件;代码如下:
1
2
|
NSUserDefaults *
saveDefaults
=
[
NSUserDefaults
standardUserDefaults
]
;
[
saveDefaults
setObject
:
arraySaveData
forKey
:
@
"已经存在的文件名"
]
;
|
arraySaveData:表示新的数据数组;