stringByEvaluatingJavaScriptFromString似乎并不总是有效

我正在开发一个Objective C应用程序,当用户滚动它时,它将一个大的HTML文档加载到UIWebView中。 这是因为文档是20Mb,如果一次加载,往往会导致webview崩溃。 我们的想法是将文档拆分为HTML块,并在用户滚动浏览时将新元素添加到文档中,并删除旧元素。

目前我正致力于将Objective C应用程序传递给文档中的javascript函数。 我有以下Objective C代码:

- (BOOL)webView:(UIWebView *)webView2 shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { NSString *url = [[request URL] absoluteString]; // Intercept custom location change, URL begins with "js-call:" if ([url hasPrefix:@"js-call:"]) { // Extract the selector name from the URL NSArray *components = [url componentsSeparatedByString:@":"]; NSString *function = [components objectAtIndex:1]; // Call the given selector [self performSelector:NSSelectorFromString(function)]; // Cancel the location change return NO; } // Accept this location change return YES; } - (void)loadNext { int endIndex = [self.partIndexEnd intValue]; int newEndIndex = endIndex + 9; if (newEndIndex >= [self.parts count] - 2){ newEndIndex = [self.parts count] - 2; } if (endIndex == newEndIndex){ return; // Already at the end of the document } int splitLen = 300; NSRange range = NSMakeRange(endIndex, newEndIndex - endIndex); for (NSString *html in [self.parts subarrayWithRange:range]) { NSLog(@"%@", html); NSString *htmlToSplit = html; while ([htmlToSplit length] > 0) { NSString *curHtml; if ([htmlToSplit length] <= splitLen){ curHtml = htmlToSplit; htmlToSplit = @""; } else { curHtml = [htmlToSplit substringToIndex:splitLen + 1]; htmlToSplit = [htmlToSplit substringFromIndex:splitLen - 1]; } NSString* result = [self.web stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"next('%@');", [curHtml gtm_stringByEscapingForAsciiHTML]]]; NSLog(@"START %@ END %@", curHtml, result); } } [self.web stringByEvaluatingJavaScriptFromString:@"next(null);"]; NSLog(@"HTML = %@ *END*", [self.web stringByEvaluatingJavaScriptFromString:@"$('body').html();"]); } 

我在文档中有以下javascript:

 var nextHtmlToAdd = ''; function next(html){ var retval = ''; try{ if (html){ if (html.match(/teststring/i)){ alert('teststring'); } nextHtmlToAdd = nextHtmlToAdd + html; retVal = 'appended'; alert(html); } else { // Finished sending HTML alert('finished'); if (nextHtmlToAdd.match(/teststring/i)){ alert('encoded html contains teststring'); } nextHtmlToAdd = $("
").html(nextHtmlToAdd).text(); if (nextHtmlToAdd.match(/teststring/i)){ alert('html contains teststring'); } alert(nextHtmlToAdd); var elem = $(nextHtmlToAdd); $('.endofsections').before(elem); if (elem.text().match(/teststring/i)){ alert('element contains teststring'); } if ($(document).text().match(/teststring/i)){ alert('document contains teststring'); } nextHtmlToAdd = ''; retVal = 'finished'; } } catch (err) { alert('Error: ' + err.description); retVal = 'error'; } return retVal; }

使用以下代码在jQuery的$(document).ready()事件中触发Objective C代码:

 var iframe = document.createElement("IFRAME"); iframe.setAttribute("src", "js-call:loadNext"); document.documentElement.appendChild(iframe); iframe.parentNode.removeChild(iframe); iframe = null; 

如果我单步执行代码,那么我看到的是运行的stringByEvaluatingJavaScriptFromString方法,并且返回’附加’作为结果或有时返回的指针无效。 Web视图中没有出现警报,并且html没有附加到nextHtmlToAdd,只有HTML的第一部分似乎正确地传递给UIWebView。

我想知道的是,stringByEvaluatingJavaScriptFromString可以执行的javascript字符串的长度是否有限制或者它可以执行的次数? 有没有其他方法可以做到这一点?

谢谢,

是的, stringByEvaluatingJavaScriptFromString方法有限制。 你需要知道的两个:

  • 不允许大于10MB的JavaScript分配
  • 不允许执行时间超过10秒的JavaScript

在前者中,您将获得一个exception,但在后者中,它可能会“无声地”失败。 你在测试方法的返回值吗? 如果失败,它将返回nil 。 由于上述原因之一,这可以是查看操作系统是否终止脚本的有用方法。