【问题标题】:iOS, stop running a function when "back" button is pressediOS,按下“后退”按钮时停止运行功能
【发布时间】:2012-03-06 13:34:06
【问题描述】:

应用程序由导航视图组成。 我在 viewDidAppear 中调用一个函数,它是

[self extractInfoWithWebsite:[NSString stringWithFormat:@"http://www.cineklik.com/%@-%@.aspx", self.cinemaType, self.location]];

此函数从 Internet 上的当前网页进行 HTML 解析。 共享代码有点长,但其想法是从网站中提取数据。

我遇到的问题是,如果用户决定在加载信息之前单击导航的后退按钮,则页面保持不变并且应用程序停止运行(不是崩溃而是变成静态的,不会'不要再做任何事情了)。

有解决办法吗? 提前谢谢你

编辑:

我将代码更改为以下内容: NSOperationQueue *queue = [NSOperationQueue 新];

    /* Create our NSInvocationOperation to call loadDataWithOperation, passing in nil */
    NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self
                                                                            selector:@selector(extractInfoWithWebsite:)
                                                                              object:[NSString stringWithFormat:@"http://www.cineklik.com/%@-%@.aspx", self.cinemaType, self.location]];

    /* Add the operation to the queue */
    [queue addOperation:operation];
    [operation release];

现在我可以按下返回按钮而不会冻结,但现在发生了崩溃并出现以下错误: 试图从除主线程或 web 线程之外的线程获取 web lock。这可能是从辅助线程调用 UIKit 的结果。现在崩溃... 我认为这是因为我的功能仍在后台运行。 如何解决这个问题?

【问题讨论】:

  • 您真的要“取消”请求吗? // 另一种解决方案(过程)可能是您使用 bgthread 之类的东西来执行这些“繁重”操作 - (当使用单独的线程时,您的主线程不会锁定)
  • 如果正在加载信息,您应该禁用用户交互并在完成时启用用户交互。
  • 另一种解决方案是在导航返回时取消加载数据

标签: iphone ios xcode html-parsing


【解决方案1】:

我会查找NSOperation

NSOperation 中的标准方法是在执行繁重的处理之前检查它们是否已被取消。

Here 是您开始研究的好链接。

编辑:我想我会澄清被取消的部分

NSOperations 有一个 main() 并且在 main() 内部最好做类似的事情

NSData* chunkyReply = nil;

if (!self.isCancelled) {
    chunkyReply = [NSURL stuff];
}    


if (!self.isCancelled) {
    //parse chunkyReply
}

【讨论】:

    【解决方案2】:

    您可以使用以下命令在后台运行加载代码:

        [self performSelectorInBackground:<#(SEL)#> withObject:<#(id)#>];
    

    然后你就可以控制按下后退按钮并捕捉它

    【讨论】:

      【解决方案3】:

      有多种不同的方法,最适合我的方法是将进程封装在您在 ViewDidLoad 中创建并在 ViewWillDisappear 中停止的 NSOperation 中。

      另一种方法是创建一个带有委托的对象,然后在离开控制器时将委托设置为零。

      【讨论】:

        【解决方案4】:

        如果不确切知道extractInfoWithWebsite: 的样子,很难给你一个更好的答案,但我假设它分为两部分:

        • 从您传递的 URL 中检索数据
        • 解析该数据

        对于第一部分,如果您使用的是[NSData dataWithContentsOfURL:...][NSURLConnection sendSynchronoushRequest:returningResponse:error:],那么您需要更改它们。这两种 URL 获取方法都不允许您取消请求。 Apple 有 good documentation 关于如何使用异步、可取消的方法。

        接下来是您对检索到的数据执行的解析。除非您从 Internet 获取数兆字节的数据,否则您的解析可能不值得取消。但是,无论如何,您都应该在后台线程中完成繁重的工作:

        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            //perform parsing
            dispatch_async(dispatch_get_main_queue(), ^{
                if (!self.view.window)
                    return; //won't update UI if we've moved offscreen
                //call methods to update the UI
            });
        });
        

        这将在默认优先级后台队列中执行解析,并在解析完成后更新主队列中的 UI(任何文本字段等)。

        是的,这是不可取消的,但就像我说的,除非您要处理 大量 数据,否则不将解析封装到 NSOperation 中可能是安全的。你会浪费一点 CPU 时间,但我会先尝试这种方法,如果性能不是你需要的,稍后更改为NSOperation。如果没有必要,早期优化毫无意义。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-06-11
          相关资源
          最近更新 更多