我在申请时遇到问题。它在模拟器中运行,但是当我尝试在设备上运行它时,它会崩溃。 我测试了它并且在将它提交给Apple进行审核之前它已经工作了,但是现在,当我试图再看一下它时,它一直在崩溃。此外,它不会在开始时崩溃,但是当我尝试导航到第二个视图时。如果你能帮我解决一下,请告诉我。谢谢!
(我已经尝试过设置NSZombieEnable,因为我在不同的帖子中找到了这个建议/答案,但它对我不起作用)
OS Version: iPhone OS 5.1.1 (9B206)
Report Version: 104
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x6f466874
Crashed Thread: 0
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 libobjc.A.dylib 0x335b2f7e objc_msgSend + 22
1 Foundation 0x34d24d04 _NSDescriptionWithLocaleFunc + 44
2 CoreFoundation 0x3597496e __CFStringAppendFormatCore + 7998
3 CoreFoundation 0x358ef1d8 _CFStringCreateWithFormatAndArgumentsAux + 68
4 Foundation 0x34d24c2e +[NSString stringWithFormat:] + 54
5 Sustain 0x00082148 +[HTMLParser parseDataForRequest:error:] (HTMLParser.m:169)
6 Sustain 0x00085a5a -[ProxyRequestResponseHandler requestFinished:] (ProxyRequestResponseHandler.m:251)
7 CoreFoundation 0x358f31f4 -[NSObject performSelector:withObject:] + 36
8 Sustain 0x00054364 -[ASIHTTPRequest reportFinished] (ASIHTTPRequest.m:2004)
9 CoreFoundation 0x358f31f4 -[NSObject performSelector:withObject:] + 36
10 Foundation 0x34dc3740 __NSThreadPerformPerform + 344
11 CoreFoundation 0x35968acc __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 8
12 CoreFoundation 0x35968298 __CFRunLoopDoSources0 + 208
13 CoreFoundation 0x3596703e __CFRunLoopRun + 646
14 CoreFoundation 0x358ea49e CFRunLoopRunSpecific + 294
15 CoreFoundation 0x358ea366 CFRunLoopRunInMode + 98
16 GraphicsServices 0x33685432 GSEventRunModal + 130
17 UIKit 0x330c2cce UIApplicationMain + 1074
18 Sustain 0x00019c26 main (main.m:16)
19 Sustain 0x00019bc0 start + 32
Thread 0 crashed with ARM Thread State:
r0: 0x00128a98 r1: 0x325894f6 r2: 0x359eccd5 r3: 0x6f46687c
r4: 0x32588417 r5: 0x00000000 r6: 0x3f3078c8 r7: 0x2fe0cb70
r8: 0x2fe0cc13 r9: 0x0c96253d r10: 0x359730b6 r11: 0x00000000
ip: 0x3f2e26f0 sp: 0x2fe0cb5c lr: 0x34d24d0b pc: 0x335b2f7e
cpsr: 0x200f0030
以下是您在HTMLParser中请求的方法
+ (BOOL)parseDataForRequest:(ASIHTTPRequest *)request error:(NSError **)error
{
NSStringEncoding encoding = [request responseEncoding];
NSString *string = [[NSString alloc] initWithContentsOfFile:[request downloadDestinationPath] usedEncoding:&encoding error:NULL];
[string release];
NSURL *baseURL = [request url];
xmlInitParser();
xmlDocPtr doc;
if ([request downloadDestinationPath]) {
doc = htmlReadFile([[request downloadDestinationPath] cStringUsingEncoding:NSUTF8StringEncoding], [self encodingNameForStringEncoding:encoding], HTML_PARSE_RECOVER | HTML_PARSE_NONET | HTML_PARSE_NOWARNING | HTML_PARSE_NOERROR);
} else {
NSData *data = [request responseData];
doc = htmlReadMemory([data bytes], (int)[data length], "", [self encodingNameForStringEncoding:encoding], HTML_PARSE_RECOVER | HTML_PARSE_NONET | HTML_PARSE_NOWARNING | HTML_PARSE_NOERROR);
}
if (doc == NULL) {
[super parseDataForRequest:request error:error];
return YES;
}
// Create xpath evaluation context
xmlXPathContextPtr xpathCtx = xmlXPathNewContext(doc);
if(xpathCtx == NULL) {
if (error) {
*error = [NSError errorWithDomain:NetworkRequestErrorDomain code:101 userInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"Error: unable to create new XPath context",NSLocalizedDescriptionKey,nil]];
}
return NO;
}
// Evaluate xpath expression
xmlXPathObjectPtr xpathObj = xmlXPathEvalExpression(xpathExpr, xpathCtx);
if(xpathObj == NULL) {
xmlXPathFreeContext(xpathCtx);
if (error) {
*error = [NSError errorWithDomain:NetworkRequestErrorDomain code:101 userInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"Error: unable to evaluate XPath expression!",NSLocalizedDescriptionKey,nil]];
}
return NO;
}
// Now loop through our matches
xmlNodeSetPtr nodes = xpathObj->nodesetval;
int size = (nodes) ? nodes->nodeNr : 0;
int i;
for(i = size - 1; i >= 0; i--) {
assert(nodes->nodeTab[i]);
NSString *parentName = [NSString stringWithCString:(char *)nodes->nodeTab[i]->parent->name encoding:encoding];
NSString *nodeName = [NSString stringWithCString:(char *)nodes->nodeTab[i]->name encoding:encoding];
xmlChar *nodeValue = xmlNodeGetContent(nodes->nodeTab[i]);
NSString *value = [NSString stringWithCString:(char *)nodeValue encoding:encoding];
xmlFree(nodeValue);
// Here we add a <base> element to the header to make the end result play better with javascript
// (UIWebView seemed to ignore the Content-Base http header when I tried)
if ([[nodeName lowercaseString] isEqualToString:@"head"]) {
xmlNodePtr node = xmlNewNode(NULL, (xmlChar *)"base");
xmlNewProp(node, (xmlChar *)"href", (xmlChar *)[[baseURL absoluteString] cStringUsingEncoding:encoding]);
node = xmlDocCopyNode(node, doc, 1);
xmlAddChild(nodes->nodeTab[i], node);
// Our xpath query matched all <link> elements, but we're only interested in stylesheets
// We do the work here rather than in the xPath query because the query is case-sensitive, and we want to match on 'stylesheet', 'StyleSHEEt' etc
} else if ([[parentName lowercaseString] isEqualToString:@"link"]) {
xmlChar *relAttribute = xmlGetNoNsProp(nodes->nodeTab[i]->parent,(xmlChar *)"rel");
if (relAttribute) {
NSString *rel = [NSString stringWithCString:(char *)relAttribute encoding:encoding];
xmlFree(relAttribute);
if ([[rel lowercaseString] isEqualToString:@"stylesheet"] || [[rel lowercaseString] isEqualToString:@"alternate stylesheet"]) {
xmlNodeSetContent(nodes->nodeTab[i], (xmlChar *)[[self localURLForURL:value withBaseURL:baseURL] cStringUsingEncoding:encoding]);
}
}
// Parse the content of <style> tags and style attributes to find external image urls or external css files
} else if ([[nodeName lowercaseString] isEqualToString:@"style"]) {
xmlNodeSetContent(nodes->nodeTab[i], (xmlChar *)[[CSSParser replaceURLsInCSSString:value withBaseURL:baseURL] cStringUsingEncoding:encoding]);
// Parse the content of <source src=""> tags (HTML 5 audio + video)
// We explictly disable the download of files with .webm, .ogv and .ogg extensions, since it's highly likely they won't be useful to us
} else if ([[parentName lowercaseString] isEqualToString:@"source"] || [[parentName lowercaseString] isEqualToString:@"audio"]) {
NSString *fileExtension = [[value pathExtension] lowercaseString];
if (![fileExtension isEqualToString:@"ogg"] && ![fileExtension isEqualToString:@"ogv"] && ![fileExtension isEqualToString:@"webm"]) {
xmlNodeSetContent(nodes->nodeTab[i], (xmlChar *)[[self localURLForURL:value withBaseURL:baseURL] cStringUsingEncoding:encoding]);
}
// For all other elements matched by our xpath query (except hyperlinks), add the content as an external url to fetch
} else if (![[parentName lowercaseString] isEqualToString:@"a"]) {
xmlNodeSetContent(nodes->nodeTab[i], (xmlChar *)[[self localURLForURL:value withBaseURL:baseURL] cStringUsingEncoding:encoding]);
}
if (nodes->nodeTab[i]->type != XML_NAMESPACE_DECL) {
nodes->nodeTab[i] = NULL;
}
}
xmlXPathFreeObject(xpathObj);
xmlXPathFreeContext(xpathCtx);
// We'll use the xmlsave API so we can strip the xml declaration
xmlSaveCtxtPtr saveContext;
if ([request downloadDestinationPath]) {
// Truncate the file first
NSFileManager *fileManager = [[[NSFileManager alloc] init] autorelease];
[fileManager createFileAtPath:[request downloadDestinationPath] contents:nil attributes:nil];
saveContext = xmlSaveToFd([[NSFileHandle fileHandleForWritingAtPath:[request downloadDestinationPath]] fileDescriptor],[self encodingNameForStringEncoding:NSUTF8StringEncoding],2|8); // 2 == XML_SAVE_NO_DECL, this isn't declared on Mac OS 10.5
xmlSaveDoc(saveContext, doc);
xmlSaveClose(saveContext);
} else {
#if TARGET_OS_MAC && MAC_OS_X_VERSION_MAX_ALLOWED <= __MAC_10_5
// xmlSaveToBuffer() is not implemented in the 10.5 version of libxml
NSString *tempPath = [NSTemporaryDirectory() stringByAppendingPathComponent:[[NSProcessInfo processInfo] globallyUniqueString]];
[[[[NSFileManager alloc] init] autorelease] createFileAtPath:tempPath contents:nil attributes:nil];
saveContext = xmlSaveToFd([[NSFileHandle fileHandleForWritingAtPath:tempPath] fileDescriptor],[self encodingNameForStringEncoding:NSUTF8StringEncoding],2|8); // 2 == XML_SAVE_NO_DECL, this isn't declared on Mac OS 10.5
xmlSaveDoc(saveContext, doc);
xmlSaveClose(saveContext);
[request setRawResponseData:[NSMutableData dataWithContentsOfFile:tempPath]];
#else
xmlBufferPtr buffer = xmlBufferCreate();
saveContext = xmlSaveToBuffer(buffer,[self encodingNameForStringEncoding:NSUTF8StringEncoding],2|8); // 2 == XML_SAVE_NO_DECL, this isn't declared on Mac OS 10.5
xmlSaveDoc(saveContext, doc);
xmlSaveClose(saveContext);
[request setRawResponseData:[[[NSMutableData alloc] initWithBytes:buffer->content length:buffer->use] autorelease]];
xmlBufferFree(buffer);
#endif
}
NSString *contentType = [[[request responseHeaders] objectForKey:@"Content-Type"] lowercaseString];
contentType = [[contentType componentsSeparatedByString:@";"] objectAtIndex:0];
if (!contentType) {
contentType = @"text/html";
}
[[request responseHeaders] setValue:[NSString stringWithFormat:@"%@; charset=utf-8"] forKey:@"Content-Type"];
[request setResponseEncoding:NSUTF8StringEncoding];
xmlFreeDoc(doc);
doc = nil;
[super parseDataForRequest:request error:error];
return YES;
}
在第二个视图中,我加载了一个在加载后缓存的webView。 我使用这个项目来获得这个: https://github.com/pokeb/ProxyingUIWebView 奇怪的是它过去曾经奏效,但现在已经不复存在了。 我试图在另一台设备上测试它,我也遇到了同样的崩溃。 这就是我在我的第二个视图控制器中所拥有的:
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
NSString *urlString = [NSString stringWithFormat:@"%@", request.URL];
NSBundle *mainBundle = [NSBundle mainBundle];
NSString *baseUrl = [mainBundle objectForInfoDictionaryKey:@"testUrl"];
if ([urlString rangeOfString:baseUrl].location != NSNotFound) //Check if URL is in-app.
{
NSURLRequest *testRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://127.0.0.1:8080/?url=http.somelink.net"]];
NSString *requestUrlString = [NSString stringWithFormat:@"%@",request.URL];
NSString *testUrlString = [NSString stringWithFormat:@"%@",testRequest.URL];
if ([requestUrlString isEqualToString:testUrlString]) //First view load
{
return YES;
}
if (navigationType == UIWebViewNavigationTypeLinkClicked ||
navigationType == UIWebViewNavigationTypeFormSubmitted ||
navigationType == UIWebViewNavigationTypeFormResubmitted ||
navigationType == UIWebViewNavigationTypeReload ||
navigationType == UIWebViewNavigationTypeOther)
{
if ([requestUrlString rangeOfString:@"Id="].location != NSNotFound) //Navigate to
{ //secondary view.
SecondaryTopTenSwapsViewController *secondaryController = [[SecondaryTopTenSwapsViewController alloc] init];
secondaryController.urlRequest = request;
[self.navigationController pushViewController:secondaryController animated:YES];
}
return NO;
}
return YES;
}
else //Not in-app URL. Check if user wants to leave application and open Safari.
{
UIAlertView *leaveApplicationAlert = [[UIAlertView alloc] initWithTitle:@"Open link?" message:@"Are you sure you want to exit the application and open the link in Safari?" delegate:self cancelButtonTitle:@"NO" otherButtonTitles:@"YES", nil];
leaveApplicationAlert.tag = 1;
[leaveApplicationAlert show];
externalUrl = request.URL;
return NO;
}
}
另外,我发现在我的辅助视图控制器中它在
之后立即崩溃-(void)webViewDidStartLoad:(UIWebView *)webView
此外,它不能是内存问题,就像我收到内存警告一样,我弹出到根视图控制器并释放所有子视图。
答案 0 :(得分:4)
您试图通过错误地转换它的格式类型来访问对象。
例如,您尝试使用格式类型%@
而不是%i
或%d
来访问整数值。
NSInteger someInteger = 255;
NSString *string = [NSString stringWithFormat:@"Hello, my favourite number is %@", someInteger"];
如果您发布一些代码,我可以概述这种情况发生的位置。
从堆栈跟踪中,看起来问题所在的字符串被传递到HTMLParser
对象是接收者的方法中。
编辑---
另一种可能性是,传递给NSString
的其中一个参数已经被释放,因为它已经被释放并且已经从内存中删除而无法访问。
编辑----
我认为问题出在这一行:
[[request responseHeaders] setValue:[NSString stringWithFormat:@"%@; charset=utf-8"] forKey:@"Content-Type"];
您使用格式字符串%@
,但不提供NSString
作为参数。
我相信您打算编写以下代码:
[[request responseHeaders] setValue:[NSString stringWithFormat:@"%@; charset=utf-8", contentType] forKey:@"Content-Type"];
答案 1 :(得分:0)
启用Zombies和Malloc Scribble(方案诊断)并调试您的应用程序(模拟器或设备或两者)。可能你有一个你正在使用的解除分配的对象。当您通过解除分配的对象或指针读取(或写入)时,随机存储器访问可能成功或失败。这是造成这种不一致行为的最常见原因。