1

我在申请时遇到问题。它在模拟器中运行,但是当我尝试在设备上运行它时,它崩溃了。在将其提交给 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

此外,这不可能是内存问题,就像我收到内存警告一样,我弹出到根视图控制器并释放所有子视图。

4

2 回答 2

4

您试图通过错误地转换其格式类型来访问对象。

例如,您尝试使用格式类型%@而不是%ior来访问整数值%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"];

您使用格式 string %@,但不提供 anNSString作为参数。

我相信您的意思是编写以下代码:

[[request responseHeaders] setValue:[NSString stringWithFormat:@"%@; charset=utf-8", contentType] forKey:@"Content-Type"];
于 2012-08-20T13:58:25.180 回答
0

打开 Zombies 和 Malloc Scribble(方案诊断)并调试您的应用程序(模拟器或设备或两者)。您可能有一个正在使用的已释放对象。当您通过释放的对象或指针读取(或写入)时,随机内存访问可能成功或失败。这是这种不一致行为的最常见原因。

于 2012-08-20T15:10:38.610 回答