nskeyedunarchiverarchiver 有数量限制吗

IOS(swift)-数据存储 · NSKeyedArchiver 归档 - 简书
下载简书移动应用
写了32555字,被236人关注,获得了127个喜欢
IOS(swift)-数据存储 · NSKeyedArchiver 归档
有一个通讯列表,可以自行添加联系数据,但是重新开启后,添加的数据都会清空,我希望打开后,上一次的数据能保留。
这我们就必须用到数据持久化,这一次,我将用NSKeyedArchiver 归档 方式来做数据持久化,达到再次打开应用后,数据依然存在。
通讯录.png
NSKeyedArchiver、NSKeyedUnarchiver ,主要用在ios数据存储上,数据从内存存储到闪存上,这个过程称为归档。Apple官方文档中,这些数据类型包括:NSData、NSString、NSNumber、NSDate、NSArray、NSDictionary。很显然,复杂数据例如UIImage,无法直接归档。但我们有一种变通的做法,先将UIImage对象转换为NSData,再对NSData进行归档。
一、创建一个数据模型(自定义类)
import UIKit
class JKContactModel: NSObject,NSCoding{
var name:NSString!
var phone:NSString!
func encodeWithCoder(aCoder: NSCoder){
aCoder.encodeObject(self.name, forKey: "name")
aCoder.encodeObject(self.phone, forKey: "phone")
required init(coder aDecoder: NSCoder) {
super.init()
self.name = aDecoder.decodeObjectForKey("name") as NSString!
self.phone = aDecoder.decodeObjectForKey("phone") as NSString!
override init() {
通过以上的代码我们可以看出,要实现对数据模型的归档,需要我们实现NScoding协议,
NScoding协议需要实现两个方法:
func encodeWithCoder(aCoder: NSCoder)
以keyValue形式对基本数据类型Encoding
init(coder aDecoder: NSCoder)
以keyValue形式对基本数据类型Decoding
二、创建一个全局路径,即要保存到闪存的位置:
let ContactFilePath = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)[0].stringByAppendingPathComponent("contacts.data")
三、从归档中读取给数组,如果第一次读取无数据,则实例化数组
这里要用到 解档方法:
NSKeyedUnarchiver.unarchiveObjectWithFile(ContactFilePath)
var contactArr:NSMutableArray?
if(contactArr == nil){
println("从归档中提取")
contactArr = NSKeyedUnarchiver.unarchiveObjectWithFile(ContactFilePath) as NSMutableArray!
if(contactArr == nil){
println("归档中没有,创建数组")
self.contactArr = NSMutableArray()
四、保存归档
在所有对数组进行操作的地方进行归档保存
NSKeyedArchiver.archiveRootObject(self.contactArr!, toFile: ContactFilePath)
归档这种保存方式缺点就是没有属性列表(NSuserDefault)速度快,因为它每次都要把文件保存到闪存中,优点是可以创建自己想要的数据模型
打赏专用:
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
被以下专题收入,发现更多相似内容:
程序员日常,代码,教程,学习笔记,谢绝推广文,软推文,软广告,blabalabala...
· 6472人关注
· 2254人关注
· 66人关注
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
选择支付方式:12872人阅读
iphone开发(140)
代码如下:NSString *str = @&abc&;
NSString *astr = @&efg&;
NSArray *Array = [NSArray arrayWithObjects:str, astr, nil];
//保存数据
NSString *Path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; NSString *filename = [Path stringByAppendingPathComponent:@&test.plist&];
[NSKeyedArchiver archiveRootObject:Array toFile:filename];
str = @&a&;
astr = @&&;
//加载数据
NSArray *arr = [NSKeyedUnarchiver unarchiveObjectWithFile: filename];
str = [arr objectAtIndex:0];
[arr objectAtIndex:1];
NSLog(@&str:%@&,str);
NSLog(@&astr:%@&,astr);&&下面是一个数据持久化的应用的实例:开发应用程序时,有一个很好的机会,你会希望有一些持久性的排序(保存名称,密码,分数等)。&NSUserDefaults提供了一个简单的方法来安全地存储信息。然而,你可能需要一个更强大的解决方案。你的逻辑数据抽象不应该有符合的持久性机制的限制,你需要一个解决方案,具有足够的灵活性来归档所有你的对象,不只是字符串,数组和字典。这就是NSKeyed(Un)Archiver的用武之地。这里的处理:我们为运动教练创建一个。他需要为他的运动员的统计资料归档/检索解决方案。讨论的规格后,我们已经打破了我们的抽象。我们有一个ScoreCard 类,将举行一个运动员的最佳时机,和所有的分数数组。我们有一个Athlete类,包含运动员的具体信息,和记分卡实例。我们有Roster类,包含了一些名册的具体信息,与运动员实例数组一起。这里是我们简单的类的代码:// ScoreCard.h
#import &Foundation/Foundation.h&
@interface ScoreCard : NSObject &NSCoding& {
NSString *bestT
NSMutableArray *allT
@property (copy) NSString *bestT
@property (copy) NSMutableArray *allT
// other methods not relevant to this tutorial go here
@implementation ScoreCard
@synthesize bestTime, allT
- (id)init {
if (self = [super init]) {
bestTime = [[NSString alloc] init];
allTimes = [[NSMutableArray alloc] init];
- (id)initWithCoder:(NSCoder *)aDecoder {
if (self = [super init]) {
bestTime = [[aDecoder decodeObjectForKey:@&bestTime&] retain];
allTimes = [[aDecoder decodeObjectForKey:@&allTimes&] retain];
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:bestTime forKey:@&bestTime&];
[aCoder encodeObject:allTimes forKey:@&allTimes&];
- (void)dealloc {
[bestTime release];
[allTimes release];
[super dealloc];
@end通过在类里声明两个方法nitWithCoder: / encodeWithCoder:,使我们的类符合NSCoding协议---当然我们已经在类里实现了这两个方法。当ScoreCard 类的对象被encoded时,必须保证它的实例变量也一起被encoded.正如你看到的,ScoreCard对象在[encodeWithCoder:]对此进行了相应处理。当然在&[initWithCoder:]方法里也做了相应的解码处理。在这里,ScoreCard对象通过NSCoder参数传过来的信息来初始化它的实例变量。这是一个优雅的解决办法;我们没有必要去关注编码/解码的过程,而ScoreCard从放进去和它的实例变量都能当成常规对象看待。对于encode/decode方法在什么时候会被唤醒你可能有一些疑问,那么请看接下来我们其它对象的代码,一切都会变得很明了。// Athlete.h
#import &Foundation/Foundation.h&
@interface Athlete : NSObject &NSCoding& {
NSString *
NSString *
NSString *phoneN
ScoreCard *scoreC
@property (copy) NSString *name, *bio, *phoneN
@property (retain) ScoreCard *scoreC
@property (getter=isEligible) BOOL
@implementation Athlete
@synthesize name, bio, phoneNumber, scoreCard,
- (id)init {
if (self = [super init]) {
name = [[NSString alloc] init];
bio = [[NSString alloc] init];
phoneNumber = [[NSString alloc] init];
scoreCard = [[ScoreCard alloc] init];
eligible = YES;
- (id)initWithCoder:(NSCoder *)aDecoder {
if (self = [super init]) {
name = [[aDecoder decodeObjectForKey:@&name&] retain];
bio = [[aDecoder decodeObjectForKey:@&bio&] retain];
phoneNumber = [[aDecoder decodeObjectForKey:@&phoneNumber&] retain];
scoreCard = [[aDecoder decodeObjectForKey:@&scoreCard&] retain];
eligible = [aDecoder decodeBoolForKey:@&eligible&];
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:name forKey:@&name&];
[aCoder encodeObject:bio forKey:@&bio&];
[aCoder encodeObject:phoneNumber forKey:@&phoneNumber&];
[aCoder encodeObject:scoreCard forKey:@&scoreCard&];
[aCoder encodeBool:eligible forKey:@&eligible&];
- (void)print {
NSLog(@&Name: %@\nBio: %@\nTel: %@\n\nBest Time: %@\n\nAll Times:&, name, bio, phoneNumber, [scoreCard bestTime]);
for (NSString *time in [scoreCard allTimes])
NSLog(@&%@&, time);
- (void)dealloc {
[name release];
[bio release];
[phoneNumber release];
[scoreCard release];
[super dealloc];
@end实际上这里没有什么新东西,除了新定义了一个BOOL变量外。只要注意在我们的编码/解码的方法来处理这种类型的原始数据的微小变化。我写了一个快速打印的方法,所以我们可以很容易地测试程序的输出。同时,正如你看到的,Athlete对象中包含一个ScoreCard实例变量。当一个Athlete对象encoded/decoded时,ScoreCard实例变量也进行同样的操作(当然所有的实例变量都会进行这样的操作,我特意指出ScoreCard实例变量只是因为它是一个定制的对象)。// Roster.h
#import &Foundation/Foundation.h&
@interface Roster : NSObject &NSCoding& {
NSMutableArray *
@property (retain) NSMutableArray *
- (void)addAthlete:(Athlete *)
@implementation Roster
@synthesize rank,
- (id)init {
if (self = [super init]) {
athletes = [[NSMutableArray alloc] init];
- (id)initWithCoder:(NSCoder *)aDecoder {
if (self = [super init]) {
athletes = [[aDecoder decodeObjectForKey:@&athletes&] retain];
rank = [aDecoder decodeIntForKey:@&rank&];
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:athletes forKey:@&athletes&];
[aCoder encodeInt:rank forKey:@&rank&];
- (void)addAthlete:(Athlete *)athlete {
[athletes addObject:athlete];
- (void)print {
NSLog(@&Roster info:\nRank: %d&, rank);
for (Athlete *athlete in athletes)
NSLog(@&%@&, [athlete name]);
- (void)dealloc {
[athletes release];
[super dealloc];
@end这里,同样的处理;这次我负责初始化和打印选手名字的工作。现在运行测试.static NSString *names [] = { @&Jeff Beck&, @&Eric Clapton&, @&Angus Young&, @&John Doe&, @&Jane Doe&, @&Shaun White&, @&Flavius Josephus& };
// function to create a roster. in real life, this wouldn't be used, but we're just testing now
Roster * create() {
NSMutableArray *scoresArray = [NSMutableArray arrayWithObjects:@&15:09:34&, @&17:54:01&, @&19:56:08&, nil];
Roster *roster = [[Roster alloc] init];
for (int i = 0; i & 7; ++i) {
Athlete *athlete = [[Athlete alloc] init];
[athlete setName:names[i]];
[athlete setBio:@&I'm a boss&];
[athlete setPhoneNumber:@&867-5309&];
[athlete.scoreCard setBestTime:@&12:30:34&];
[athlete.scoreCard setAllTimes:scoresArray];
[roster addAthlete:athlete];
return [roster autorelease];
int main (int argc, char **argv) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// create and archive a roster
Roster *roster = create();
[NSKeyedArchiver archiveRootObject:roster toFile:@&/roster.archive&];
// unarchive roster
Roster *roster = [NSKeyedUnarchiver unarchiveObjectWithFile:@&/roster.archive&];
[roster print];
for (Athlete *athlete in [roster athletes])
[athlete print];
[pool drain];
}程序第一次运行时,一个Roster对象被创建,填充和存档。去除下面几行的注释,你就可心从档案里创建一个Roster对象。&
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1133896次
积分:12638
积分:12638
排名:第708名
原创:94篇
转载:407篇
评论:164条
◆分析你所使用的技术其原理和背后运行的机制,这样可以提高你的技术判断力,提高你技术方案选择的正确性; ◆学习大学期间重要的知识, 操作系统原理,数据结构和算法。知道你以前学习都是为了考试,但现在你需要为自己学习,让自己知其所以然; ◆重新开始学习C语言,虽然你在大学已经学过。这不仅是因为你可能需要写PHP扩展,而且还因为,在做C的应用中,有一个时刻关心性能、内存控制、变量生命周期、数据结构和算法的环境;
◆学习面向对象的分析与设计,它是解决复杂问题的有效的方法。学习抽象,它是解决复杂问题的唯一之道。
(1)(5)(8)(2)(2)(1)(2)(2)(6)(12)(33)(8)(17)(3)(6)(7)(8)(8)(2)(6)(8)(14)(11)(18)(19)(2)(1)(6)(6)(14)(2)(20)(24)(27)(18)(22)(45)(8)(10)(11)(12)(12)(8)(8)(23)(1)(3)(1)(2)(1)(2)(3)(2)1491人阅读
iphone开发(186)
今天遇到一个反馈:在程序中用NSKeyedArchiver保存用户资料时,导致程序退出情况。源代码如下:
if (sectionCount &= 5) {
//保存数据到本地,防止每次进入都请求数据
NSString * filePath =
if (canEdit) {
filePath = [Func getAppDocumentsPath:[NSString stringWithFormat:@&myaccount_%d.plist&, taonanApi.currentUserId]];
filePath = [Func getAppTmpPath:[NSString stringWithFormat:@&myaccount_%@.plist&, [userProfile objectForKey:@&friendid&]]];
[NSKeyedArchiver archiveRootObject:detailProfile toFile:filePath];
查找资料后发现原因如下:使用NSKeyedArchiver保存的对象,其自身及以及属性(或集合中的对象)必须是实现了NSCoding协议的对象才能正确保存。而在detailProfile中,有一个UIImage对象被无意中使用NSDictionary的addEntriesFromDictionary添加进来,导致最后保存时程序报错退出。
解决方案:
1、不要向要使用NSKeyedArchiver保存的对象添加没有实现NSCoding协议的对象。
2、如果不确定是否有无意中添加其他不支持的对象,在使用NSKeyedArchiver保存数据前,排除所有没有实现NSCoding的对象。代码如下:
for (NSString * sectkey in detailProfile) {
if ([sectkey isEqualToString:SECTION_0_NAME] || [sectkey isEqualToString:SECTION_1_NAME]) {
NSMutableDictionary * sectData = [[detailProfile objectForKey:sectkey] objectAtIndex:0];
for (NSString * dkey in sectData) {
if (![[sectData objectForKey:dkey] conformsToProtocol:@protocol(NSCoding)]) {
[sectData removeObjectForKey:dkey];
最后总结一句:写代码一定要小心,在添加对象到集合、赋值等操作时,能明确的限定范围的,一定要限定范围。否则可能产生和多意料之外的错误。
血的教训啊!!!
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:541327次
积分:5032
积分:5032
排名:第3801名
原创:68篇
转载:171篇
评论:77条
(2)(1)(1)(1)(1)(1)(5)(1)(2)(1)(1)(1)(1)(3)(3)(2)(1)(7)(7)(10)(10)(19)(11)(11)(5)(1)(5)(4)(7)(5)(21)(10)(82)NSKeyed archiver warnings using unique keys [nskeyed归档警告使用唯一的键] - 问题-字节技术
NSKeyed archiver warnings using unique keys
nskeyed归档警告使用唯一的键
问题 (Question)
I am getting multiple log warnings like this when I put my app into the background using the home button when testing preservation / state restoration.
20:13:08.275 FlowTrak[16777:60b] *** NSKeyedArchiver warning: replacing existing
value for key 'UIStateRestorationViewControllerStoryboard'; probable duplication of encoding
keys in class hierarchy
The app runs fine on the device, and all of the state restoration / preservation works as it should, but I would love to get rid of these warnings. There is not a ton of info about these warnings out there, but from what I have read, I should be good to go so long as I am using unique keys for each UI item I am preserving.
Any ideas on sorting this out? Thanks.
Here is my code:
// Restoration of text fields
-(void)encodeRestorableStateWithCoder:(NSCoder *)coder
// start level text
[coder encodeObject:_startLevel.text forKey:@"startText"];
[super encodeRestorableStateWithCoder:coder];
// stop level text
[coder encodeObject:_stopLevel.text forKey:@"stopText"];
[super encodeRestorableStateWithCoder:coder];
// start time label
[coder encodeObject:_startTimeLabel.text forKey:@"startTimeText"];
[super encodeRestorableStateWithCoder:coder];
// stop time label
[coder encodeObject:_stopTimeLabel.text forKey:@"stopTimeText"];
[super encodeRestorableStateWithCoder:coder];
// minute rate label
[coder encodeObject:_minuteRateLabel.text forKey:@"minuteRateText"];
[super encodeRestorableStateWithCoder:coder];
// start segmented control
[coder encodeInteger:self.startFractionControl.selectedSegmentIndex forKey:@"startIndex"];
[super encodeRestorableStateWithCoder:coder];
// stop segmented control
[coder encodeInteger:self.stopFractionControl.selectedSegmentIndex forKey:@"stopIndex"];
[super encodeRestorableStateWithCoder:coder];
// start button state
[coder encodeBool:self.start.enabled forKey:@"startButtonState"];
[super encodeRestorableStateWithCoder:coder];
// stop button state
[coder encodeBool:self.stop.enabled forKey:@"stopButtonState"];
[super encodeRestorableStateWithCoder:coder];
// calculate button state
[coder encodeBool:self.calculate.enabled forKey:@"calculateButtonState"];
[super encodeRestorableStateWithCoder:coder];
// resume button state
[coder encodeBool:self.resume.enabled forKey:@"resumeButtonState"];
[super encodeRestorableStateWithCoder:coder];
// tank selector segmented control
[coder encodeInteger:self.tankControl.selectedSegmentIndex forKey:@"tankIndex"];
[super encodeRestorableStateWithCoder:coder];
// start time for equation
[coder encodeDouble:startTime forKey:@"startTimeEquation"];
[super encodeRestorableStateWithCoder:coder];
// stop time for equation
[coder encodeDouble:stopTime forKey:@"stopTimeEquation"];
[super encodeRestorableStateWithCoder:coder];
// start segmented control for equation
[coder encodeObject:startFractions forKey:@"startFractionsEquation"];
[super encodeRestorableStateWithCoder:coder];
// stop segmented control for equation
[coder encodeObject:stopFractions forKey:@"stopFractionsEquation"];
[super encodeRestorableStateWithCoder:coder];
// tank selector segmented control for equation
[coder encodeBool:bigTank forKey:@"bigTankEquation"];
[super encodeRestorableStateWithCoder:coder];
-(void)decodeRestorableStateWithCoder:(NSCoder *)coder
// start level text
_startLevel.text = [coder decodeObjectForKey:@"startText"];
[super decodeRestorableStateWithCoder:coder];
// stop level text
_stopLevel.text = [coder decodeObjectForKey:@"stopText"];
[super decodeRestorableStateWithCoder:coder];
// start time label
_startTimeLabel.text = [coder decodeObjectForKey:@"startTimeText"];
[super decodeRestorableStateWithCoder:coder];
// stop time label
_stopTimeLabel.text = [coder decodeObjectForKey:@"stopTimeText"];
[super decodeRestorableStateWithCoder:coder];
// minute rate label
_minuteRateLabel.text = [coder decodeObjectForKey:@"minuteRateText"];
[super decodeRestorableStateWithCoder:coder];
// start segmented control
self.startFractionControl.selectedSegmentIndex = [coder decodeIntegerForKey:@"startIndex"];
[super decodeRestorableStateWithCoder:coder];
// stop segmented control
self.stopFractionControl.selectedSegmentIndex = [coder decodeIntegerForKey:@"stopIndex"];
[super decodeRestorableStateWithCoder:coder];
// start button state
self.start.enabled = [coder decodeBoolForKey:@"startButtonState"];
[super decodeRestorableStateWithCoder:coder];
// stop button state
self.stop.enabled = [coder decodeBoolForKey:@"stopButtonState"];
[super decodeRestorableStateWithCoder:coder];
// calculate button state
self.calculate.enabled = [coder decodeBoolForKey:@"calculateButtonState"];
[super decodeRestorableStateWithCoder:coder];
// resume button state
self.resume.enabled = [coder decodeBoolForKey:@"resumeButtonState"];
[super decodeRestorableStateWithCoder:coder];
// tank selector segmented control
self.tankControl.selectedSegmentIndex = [coder decodeIntegerForKey:@"tankIndex"];
[super decodeRestorableStateWithCoder:coder];
// start time for equation
startTime = [coder decodeDoubleForKey:@"startTimeEquation"];
[super decodeRestorableStateWithCoder:coder];
// stop time for equation
stopTime = [coder decodeDoubleForKey:@"stopTimeEquation"];
[super decodeRestorableStateWithCoder:coder];
// start segmented control for equation
startFractions = [coder decodeObjectForKey:@"startFractionsEquation"];
[super decodeRestorableStateWithCoder:coder];
// stop segmented control for equation
stopFractions = [coder decodeObjectForKey:@"stopFractionsEquation"];
[super decodeRestorableStateWithCoder:coder];
// calculate button state
bigTank = [coder decodeBoolForKey:@"bigTankEquation"];
[super decodeRestorableStateWithCoder:coder];
我得到多个日志警告,这样当我把我的应用程序在后台使用主页按钮保存/恢复测试时的状态。 20:13:08.275 FlowTrak[16777:60b] *** NSKeyedArchiver warning: replacing existing
value for key 'UIStateRestorationViewControllerStoryboard'; probable duplication of encoding
keys in class hierarchy
应用程序运行在设备优良,和所有的状态恢复/保护工作是必须的,但我想摆脱这些警告。没有大量关于这些警告信息了,但我已阅读,我应该很好的去只要我使用唯一的密钥对每个UI项我保留。在整理这出什么主意吗?感谢这里是我的代码:// Restoration of text fields
-(void)encodeRestorableStateWithCoder:(NSCoder *)coder
// start level text
[coder encodeObject:_startLevel.text forKey:@"startText"];
[super encodeRestorableStateWithCoder:coder];
// stop level text
[coder encodeObject:_stopLevel.text forKey:@"stopText"];
[super encodeRestorableStateWithCoder:coder];
// start time label
[coder encodeObject:_startTimeLabel.text forKey:@"startTimeText"];
[super encodeRestorableStateWithCoder:coder];
// stop time label
[coder encodeObject:_stopTimeLabel.text forKey:@"stopTimeText"];
[super encodeRestorableStateWithCoder:coder];
// minute rate label
[coder encodeObject:_minuteRateLabel.text forKey:@"minuteRateText"];
[super encodeRestorableStateWithCoder:coder];
// start segmented control
[coder encodeInteger:self.startFractionControl.selectedSegmentIndex forKey:@"startIndex"];
[super encodeRestorableStateWithCoder:coder];
// stop segmented control
[coder encodeInteger:self.stopFractionControl.selectedSegmentIndex forKey:@"stopIndex"];
[super encodeRestorableStateWithCoder:coder];
// start button state
[coder encodeBool:self.start.enabled forKey:@"startButtonState"];
[super encodeRestorableStateWithCoder:coder];
// stop button state
[coder encodeBool:self.stop.enabled forKey:@"stopButtonState"];
[super encodeRestorableStateWithCoder:coder];
// calculate button state
[coder encodeBool:self.calculate.enabled forKey:@"calculateButtonState"];
[super encodeRestorableStateWithCoder:coder];
// resume button state
[coder encodeBool:self.resume.enabled forKey:@"resumeButtonState"];
[super encodeRestorableStateWithCoder:coder];
// tank selector segmented control
[coder encodeInteger:self.tankControl.selectedSegmentIndex forKey:@"tankIndex"];
[super encodeRestorableStateWithCoder:coder];
// start time for equation
[coder encodeDouble:startTime forKey:@"startTimeEquation"];
[super encodeRestorableStateWithCoder:coder];
// stop time for equation
[coder encodeDouble:stopTime forKey:@"stopTimeEquation"];
[super encodeRestorableStateWithCoder:coder];
// start segmented control for equation
[coder encodeObject:startFractions forKey:@"startFractionsEquation"];
[super encodeRestorableStateWithCoder:coder];
// stop segmented control for equation
[coder encodeObject:stopFractions forKey:@"stopFractionsEquation"];
[super encodeRestorableStateWithCoder:coder];
// tank selector segmented control for equation
[coder encodeBool:bigTank forKey:@"bigTankEquation"];
[super encodeRestorableStateWithCoder:coder];
-(void)decodeRestorableStateWithCoder:(NSCoder *)coder
// start level text
_startLevel.text = [coder decodeObjectForKey:@"startText"];
[super decodeRestorableStateWithCoder:coder];
// stop level text
_stopLevel.text = [coder decodeObjectForKey:@"stopText"];
[super decodeRestorableStateWithCoder:coder];
// start time label
_startTimeLabel.text = [coder decodeObjectForKey:@"startTimeText"];
[super decodeRestorableStateWithCoder:coder];
// stop time label
_stopTimeLabel.text = [coder decodeObjectForKey:@"stopTimeText"];
[super decodeRestorableStateWithCoder:coder];
// minute rate label
_minuteRateLabel.text = [coder decodeObjectForKey:@"minuteRateText"];
[super decodeRestorableStateWithCoder:coder];
// start segmented control
self.startFractionControl.selectedSegmentIndex = [coder decodeIntegerForKey:@"startIndex"];
[super decodeRestorableStateWithCoder:coder];
// stop segmented control
self.stopFractionControl.selectedSegmentIndex = [coder decodeIntegerForKey:@"stopIndex"];
[super decodeRestorableStateWithCoder:coder];
// start button state
self.start.enabled = [coder decodeBoolForKey:@"startButtonState"];
[super decodeRestorableStateWithCoder:coder];
// stop button state
self.stop.enabled = [coder decodeBoolForKey:@"stopButtonState"];
[super decodeRestorableStateWithCoder:coder];
// calculate button state
self.calculate.enabled = [coder decodeBoolForKey:@"calculateButtonState"];
[super decodeRestorableStateWithCoder:coder];
// resume button state
self.resume.enabled = [coder decodeBoolForKey:@"resumeButtonState"];
[super decodeRestorableStateWithCoder:coder];
// tank selector segmented control
self.tankControl.selectedSegmentIndex = [coder decodeIntegerForKey:@"tankIndex"];
[super decodeRestorableStateWithCoder:coder];
// start time for equation
startTime = [coder decodeDoubleForKey:@"startTimeEquation"];
[super decodeRestorableStateWithCoder:coder];
// stop time for equation
stopTime = [coder decodeDoubleForKey:@"stopTimeEquation"];
[super decodeRestorableStateWithCoder:coder];
// start segmented control for equation
startFractions = [coder decodeObjectForKey:@"startFractionsEquation"];
[super decodeRestorableStateWithCoder:coder];
// stop segmented control for equation
stopFractions = [coder decodeObjectForKey:@"stopFractionsEquation"];
[super decodeRestorableStateWithCoder:coder];
// calculate button state
bigTank = [coder decodeBoolForKey:@"bigTankEquation"];
[super decodeRestorableStateWithCoder:coder];
最佳答案 (Best Answer)
Why are you calling super's implementation multiple times? Only call it once!
为什么你叫超级实施多次吗?只打一次!
本文翻译自StackoverFlow,英语好的童鞋可直接参考原文:

我要回帖

更多关于 ios nskeyedarchiver 的文章

 

随机推荐