菜鸟教程小白 发表于 2022-12-12 09:43:25

iOS 在解除 ViewController 时停止 for 循环内的所有当前处理


                                            <p><p>我正在使用下面的代码,该代码在嵌入 <code>UITableView</code> 的 <code>UIViewController</code> 中调用。
它遍历一个位置列表,创建 <code>NSURL</code> 并将其传递给 <code>NSXMLParser</code>。一切都按预期进行。</p>

<p>但是,如果用户单击后退按钮,我希望不仅 <code>UIViewController</code> 被解除并且用户返回到我之前的 <code>UIViewController</code>已经,但我希望与 <code>-(void)getInfo</code> 和 <code>NSXMLParser</code> 中发生的 <code>for 循环</code> 相关的处理立即终止如果它确实仍在运行。 </p>

<p>在大多数情况下,处理将完成,这不会成为问题,但是,在某些情况下,这可能需要更长的时间,我不希望代码在按下后继续运行, 因为这样就不需要数据了,因此只会浪费资源,并且由于处理多个 <code>NSURL</code> s,在返回到前一个 UIViewController 时可能会阻塞 UI。</p >

<pre><code>-(void)getInfo{
    NSDictionary *places = [ initWithContentsOfFile:[ pathForResource:@&#34;places&#34; ofType:@&#34;plist&#34;]];
    NSArray *placescc = [ initWithArray:places.allKeys];
    __block NSUInteger placewaiting = placescc.count;
    NSUserDefaults *defaults = ;
    NSDictionary *savedLocs = [mutableCopy]; //got savedLocs
    NSDictionary *thisLoc = [mutableCopy]; //got this Loc

    lastInfoCount = 0; // set default
    if ([count]){
      lastInfoCount = [count]; // set saved count if we have one
    }

    for (NSString *place in placescc) {
      dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            NSURL *url = ];
            NSXMLParser *parser = [ initWithContentsOfURL:url];

            dispatch_async(dispatch_get_main_queue(), ^{
                ;
                ;
                ;

                placewaiting = placewaiting-1;
                if (placewaiting == 0){

                  ;
                  ;
                  lastRefresh = ];
                }
            });
      });
    }
}
</code></pre></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>我建议使用 NSOperationQueue 和 NSBlockOperation 然后您可以取消在 dealloc(或可能是 viewWillDisappear)中的操作以及在 GCD 线程测试 isCanceled 上执行的 block 内并退出/跳过 UI 更新。但是,您必须确保对 ViewController 的弱引用,否则执行 block 将保留 Controller 。像这样的:</p>

<pre><code>// @property(nonatomic,weak) NSBlockOperation *backgroundOperation;

+ (NSOperationQueue*)operationQueue
{
    static dispatch_once_t onceToken;
    static NSOperationQueue *operationQueue;
    dispatch_once(&amp;onceToken, ^{
      operationQueue = [ init];
    });

    return operationQueue;
}

- (NSOperationQueue*)operationQueue
{
    return [ operationQueue];
}

- (void)dealloc
{
    ;
}

- (void)getInfo
{
    NSDictionary *places = [ initWithContentsOfFile:[ pathForResource:@&#34;places&#34; ofType:@&#34;plist&#34;]];
    NSArray *placescc = [ initWithArray:places.allKeys];
    __block NSUInteger placewaiting = placescc.count;
    NSUserDefaults *defaults = ;
    NSDictionary *savedLocs = [mutableCopy]; //got savedLocs
    NSDictionary *thisLoc = [mutableCopy]; //got this Loc

    lastInfoCount = 0; // set default
    if ([count]){
      lastInfoCount = [count]; // set saved count if we have one
    }

    // Ensure previous operation finished
    ;

    NSBlockOperation *op = [ init];
    self.backgroundOperation = op;
    __weak NSBlockOperation *weakOp = op;
    __weak typeof(self) weakSelf = self;

    [op addExecutionBlock:^{
      NSURL *url = ];
      NSXMLParser *parser = [ initWithContentsOfURL:url];
      if (weakOp &amp;&amp; !weakOp.isCancelled)
      {
            dispatch_async(dispatch_get_main_queue(), ^{
                ;
                ;
                ;

                placewaiting = placewaiting-1;
                if (placewaiting == 0){

                  ;
                  ;
                  lastRefresh = ];
                }
            });
      }
    }];

    [ addOperation:op];
}
</code></pre>

<p>请注意,weakSelf、weakOp 和 backgroundOperation 属性在其引用的对象被释放时将自动为 null,因此如果在 ViewController 关闭后执行 block 中的 UI 更新代码,weakSelf.tableView/activityIndi​​cator 将为 null 并且没有操作。在您的情况下,因为大部分工作是同步检索和解析数据,因此不会中止,但上面的代码意味着 ViewController 将立即释放,并且 ViewController 上的 UI 更新变为无操作。</p ></p>
                                   
                                                <p style="font-size: 20px;">关于iOS 在解除 ViewController 时停止 for 循环内的所有当前处理,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/23492250/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/23492250/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: iOS 在解除 ViewController 时停止 for 循环内的所有当前处理