如何解决在@Property上加载首选项时,应用程序崩溃EXC_BAD_ACCESS
|| 这是许多EXC_BADACCES问题之一,但我已经进行了很长时间的研究,并认为此问题尚未得到解答。我的应用程序使用首选项保存数据。如果我删除首选项并启动该应用程序,那么一切进展顺利,因此根本不会发生任何加载。但是,如果加载发生问题。我必须保存一个包含自写对象Box的主数组。一个Box有一个NSString * boxName,六个NSMutableArray *包含另一个自写对象,称为Flashcard wich,其中包含两个NSString *:问与答。如果AppDelegate获得消息applicationWillTerminate,它将使用NSKeyedArchiver对主数组(称为boxArray)进行编码,并将其保存在首选项中。在AppControll的init方法中,此存档是从首选项中加载的:- (id)init {
self = [super init];
if (self) {
// Initialization code here.
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
NSData* archive = [defaults objectForKey:@\"boxArray\"];
if (archive) {
NSArray* array = [NSKeyedUnarchiver unarchiveObjectWithData:archive];
boxArray = [NSMutableArray arrayWithArray:array];
} else {
boxArray = [[NSMutableArray alloc] init];
}
}
return self;
}
在Box的encodeWithCoder方法中,它会为其所有数组创建单独的NSData *对象,如下所示。
NSData* p1archv = [NSKeyedArchiver archivedDataWithRootObject:phase1];
[aCoder encodeObject:p1archv forKey:@\"phase1\"];
它会像这样加载所有内容:
NSData * p1archv = [aDecoder encodeObjectObjectKey:@ \“ phase1 \”];
if (p1archv) {
NSArray* a = [NSKeyedUnarchiver unarchiveObjectWithData:p1archv];
phase1 = [NSMutableArray arrayWithArray:a];
NSLog(@\"loaded phase1: %@\",phase1);
} else {
phase1 = [[NSMutableArray alloc] init];
NSLog(@\"inited phase1\");
}
它保存自己的框名称,如下所示:
[aCoder encodeObject:boxName forKey:@ \“ boxName \”];
加载是这样的:
boxName = [aDecoder decodeObjectForKey:@\"boxName\"];
抽认卡encodeWithCoder:
- (void) encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:question forKey:@\"question\"];
[aCoder encodeObject:answer forKey:@\"answer\"];
NSLog(@\"encoded %@ and %@\",question,answer);
}
和initWithCoder:
- (id) initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self) {
// Initialization code here.
question = [aDecoder decodeObjectForKey:@\"question\"];
answer = [aDecoder decodeObjectForKey:@\"answer\"];
}
return self;
}
好的,现在您知道了实际的设置,但这是我的实际问题是:
如果应用程序启动,并且有要加载的首选项,它将在Box.h文件中崩溃。
确切地说,它在此行崩溃:
@property (readwrite,copy) NSString* boxName;
与EXC_BAD_ACCESS。我打开了NSZombieEnabled,它显示了完全相同的行。
在我的研究中,我对每种方法都进行了制衡,结果发现,在使用Box的编码器方法进行初始化的过程中,一切正常,boxName应该是正确的(例如\“ foo \”),但如果使用tableview (由NSArrayController管理)想要将数据加载到表视图中,该视图在运行时崩溃或显示诸如\“ 1:918 \”单步执行。我确定,在加载过程之前,我还没有发布数组,boxName或任何东西,因此无法解释此问题。如果您能帮助我,我将非常高兴,Elemantosque
解决方法
我怀疑您的问题是,decodeObjectForKey总是会返回一个自动释放的对象。因此:
boxName = [aDecoder decodeObjectForKey:@\"boxName\"]; // AUTORELEASED!!!
将一个字符串粘贴到boxName中,该字符串最终将消失,然后得到一个丑陋的语法表。还定义为以下属性:
@property (readwrite,copy) NSString* boxName;
当我会使用:
@property (readwrite,retain) NSString* boxName;
然后在代码中使用以下内容:
self.boxName = [aDecoder decodeObjectForKey:@\"boxName\"]; // HAVE TO USE self.boxName
要做的是将字符串保留在boxName中。我的猜测是,如果更改属性行和赋值行,您的错误将消失(尽管您可能还有其他错误)。
如果您不想更改属性行,则可以使用:
[boxName autorelease]; // to be on the safe side
boxName = [[aDecoder decodeObjectForKey:@\"boxName\"] retain]; // no more uglygram
经验法则:除非您使用[alloc],否则请假定该对象是自动释放的。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。