【问题标题】:Stopping Asynchronous Block Request when Leaving View (AFNetworking; iOS)离开视图时停止异步阻止请求(AFNetworking;iOS)
【发布时间】:2014-06-19 22:53:13
【问题描述】:

我正在使用 AFNetworking (2.3.1) 解析 JSON 数据并将其显示在标签中。

为此,我使用setCompletionBlockWithSuccess,它在AFHTTPRequestOperation.h 中声明。

viewDidLoad 上调用了三个这样的函数,一个看起来像:

-(void)parse {

    NSURL *url = [[NSURL alloc] initWithString:kURL];
    NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];

    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
    operation.responseSerializer = [AFJSONResponseSerializer serializer];

    [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {

        NSLog(@"Parse Successful");
        //Code for JSON Parameters and to display data


    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {

        NSLog(@"%@", [error localizedDescription]);
        //Code for Failure Handling

    }];

    [operation start];

}

虽然这就像一个魅力,因为它包含在一个块请求中,这个过程会在整个应用程序状态中继续进行。因此,当不需要显示此数据时,请求仍在加载,并且由于这些块,我收到了内存警告。

我的问题是,一旦我离开创建它们的 View Controller 以节省内存和数据,或适当地处理它们,如何停止、取消或暂停这些进程?

如果这是一个明显的答案,请原谅我,我只是以完全错误的方式处理或创建块。我对 AFNetworking 和块、操作、异步请求等都是新手。

谢谢。

【问题讨论】:

    标签: ios objective-c afnetworking objective-c-blocks nsoperation


    【解决方案1】:

    假设你有一个名为 operation 的 AFHTTPRequestOperation 对象:

    [operation cancel];
    

    这可能属于 ViewWillDisappear。

    然后在你的失败块(随后将被调用)中,你可以检查它是否因为错误而失败,或者你是否取消了它:

    if ([operation isCancelled])
    {
         //I canceled it.
    }
    

    更新 - 一个更具体的示例,说明如何保存对操作的引用并在视图消失时取消它。

    @interface myViewController ()
    
    @property (strong, nonatomic) AFHTTPRequestOperation *parseOperation;
    
    @end
    
    @implementation myViewController
    
    - (void)viewWillDisappear:(BOOL)animated
    {
        [super viewWillDisappear:animated];
    
    //no need to check to see if the operation is nil (because it never happened or it's complete) because
    //messages sent to nil are ok.
    [self.parseOperation cancel];
    }
    
    -(void)parse {
    
    NSURL *url = [[NSURL alloc] initWithString:kURL];
    NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];
    
    //save the parse operation so we can cancel it later on if we need to
    self.parseOperation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
    self.parseOperation.responseSerializer = [AFJSONResponseSerializer serializer];
    
    __weak myViewController *weakSelf = self;
    [self.parseOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
        //nil out the operation we saved earlier because now that it's finished we don't need to cancel it anymore
        weakSelf.parseOperation = nil;
    
        NSLog(@"Parse Successful");
        //Code for JSON Parameters and to display data
    
    
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        if (!operation.isCancelled) {
        NSLog(@"%@", [error localizedDescription]);
        //Code for Failure Handling
        }
    }];
    
    [self.parseOperation start];
    }
    

    【讨论】:

    • 我之前检查过取消操作,但是有问题。一旦我在 void 语句之外声明了操作(以便可以引用它被取消),我会收到一个警告,您可以看到 here。我知道这与 are 和 __weak、__block 之类的声明有关。你能在这里指出我正确的方向吗?另外,NSOperations 取消后可以重新启动不是吗?
    • 链接中的警告可能是因为变量 bTCAverage 是该类的一个实例变量,并且正在从块内访问它,因此它可以创建一个保留周期。我用更具体的例子更新了我的答案。
    【解决方案2】:

    事实证明,没有停止是由于一个计时器(称为块请求,或函数parse)在视图消失后没有失效。使-(void)viewDidDisappear: 上的计时器无效解决了这个问题。

    【讨论】:

    • @hfz [timer invalidate];
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-02-19
    • 1970-01-01
    • 1970-01-01
    • 2019-08-17
    • 1970-01-01
    • 2016-12-11
    • 1970-01-01
    相关资源
    最近更新 更多