【发布时间】:2010-09-26 02:17:32
【问题描述】:
我收到了来自 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 的二进制文件中的某些内容已损坏。我怀疑这是答案,因为这些二进制文件是校验和的,但我在这里没有想法了。如果它会在测试人员的手机上再次崩溃,我不想只是重新提交。
【问题讨论】:
-
很遗憾,您无法重新创建崩溃。在我看来,从堆栈跟踪来看,您传递给 -[Tumblelog initWithDictionary:] 的任何内容实际上都不是 NSDictionary。然后该方法对其调用 NSDictionary 方法,导致“无法识别选择器”异常。您确定 tumblelogs 数组中的每个对象始终是一个 NSDictionary(即文档的 toDictionary 中键 kParseKeyPathTumblelogsInfo 的值始终是一个 NSDictionaries 数组)?
-
我不熟悉 NSXMLDocument toDictionary (并且找不到文档?)知道这一点,但可以保证
[dictionary valueForKeyPath:kParseKeyPathTumblelogsInfo]将返回一个 NSArray 的 NSDictionary 实例吗?您根本没有进行任何错误检测,即传入数据符合您期望的 XML。 -
非常好的点。接收格式与我预期不同的响应数据肯定是问题所在。我正计划像@imaginaryboy 建议的那样添加错误检查。在正常情况下,格式错误的 XML 响应不会深入到代码中,它们会更早地被发现。我担心这不是问题,我只是重新提交一个会再次被拒绝的应用程序。
标签: iphone objective-c crash release