我收到了Apple的崩溃报告,我正试图确定发生了什么。我无法按照他们的步骤重新创建崩溃,我在任何测试中都没有看到类似的崩溃。以下是崩溃报告的重要部分:
9 libobjc.A.dylib 0x00004838 objc_exception_throw + 64
10 CoreFoundation 0x000a167c -[NSObject(NSObject) doesNotRecognizeSelector:] + 96
11 CoreFoundation 0x000491d2 ___forwarding___ + 502
12 CoreFoundation 0x00048f88 _CF_forwarding_prep_0 + 40
13 TheApp 0x0001cd28 -[Tumblelog initWithDictionary:] (Tumblelog.m:40)
14 TheApp 0x0001ef8c -[TumblrEngine userFromRequest:] (TumblrEngine.m:589)
这让我觉得我的字典过早发布了。这个代码路径在应用程序的大多数运行期间被多次调用,它还没有为我崩溃,所以我有信心我不会意外地将错误的对象发送到initWithDictionary
。
以下是来自TumblrEngine
和Tumblelog
的代码。
// TumblrEngine.m
- (TumblrUser *)userFromRequest:(ASIHTTPRequest *)request{
NSData *data = [request responseData];
NSError *parseError = nil;
NSXMLDocument *doc = [[[NSXMLDocument alloc] initWithData:data options:NSXMLDocumentTidyXML error:&parseError] autorelease];
NSDictionary *dictionary = [doc toDictionary];
NSDictionary *userDict = [dictionary valueForKeyPath:kParseKeyPathUserInfo];
TumblrUser *user = [[TumblrUser alloc] initWithDictionary:userDict];
NSArray *tumblelogs = [dictionary valueForKeyPath:kParseKeyPathTumblelogsInfo];
NSMutableArray *userTumblelogs = [NSMutableArray array];
for(NSDictionary *tumblelogDictionary in tumblelogs){
Tumblelog *tumblelog = [[Tumblelog alloc] initWithDictionary:tumblelogDictionary]; //line 589
[userTumblelogs addObject:tumblelog];
[tumblelog release];
}
[user setTumblelogs:userTumblelogs];
return [user autorelease];
}
// Tumblelog.m
- (id)initWithDictionary:(NSDictionary *)aDictionary{
if((self = [super init])){
[self setAvatarURL:[aDictionary restURLForKey:kParseKeyTumblelogAvatarURL]]; //line 40
// this was the line that started the crash
}
return self;
}
我的主要问题是:您是否看到aDictionary
在创建时和我尝试在Tumblelog.m
中使用它之间的任何时间点如何发布?
否则,我正在探索在NSDictionary
加载类别时是否存在问题。当我将应用程序直接加载到我的三款测试手机(iPhone 4 / iOS 4.1,iPhone 3GS / iOS 4.0.1,iPhone 3G / 3.1.3)上时,它工作正常。该应用程序崩溃的手机是iPhone 4 / iOS 4.1,与我的主要测试手机相同。
我能想到的其他事情可能就是我发送的二进制文件Apple已损坏。我很怀疑这是答案,因为那些二进制文件已被检查,但我在这里已经没有想法了。如果它再次在测试仪的手机上崩溃,我不想再重新提交。
答案 0 :(得分:1)
这可能是一个线程问题(对象在另一个线程上被释放),但上面的代码似乎不太可能。
很可能(正如@imaginaryboy所说)你没有字典。
更安全的循环看起来像这样。
for(id tumblelogDictionary in tumblelogs){
if ([tumblelogDictionary isKindOfClass:[NSDictionary class]]) {
Tumblelog *tumblelog = [[Tumblelog alloc] initWithDictionary:tumblelogDictionary]; //line 589
[userTumblelogs addObject:tumblelog];
[tumblelog release];
} else {
// Appropriate error handling and / or logging.
}
}
注意:我实际上没有尝试过编译。它可能有一两个拼写错误或语法错误。