【问题标题】:How to stop call which is sent in operation queue in Objective-C如何停止在Objective-C的操作队列中发送的调用
【发布时间】:2016-06-12 03:43:32
【问题描述】:

我正在开发 iOS 应用程序,并且正在使用 AFNetworking 与服务器 API 进行交互。 我的问题是我想发送呼叫并且不想限制用户,直到从服务器获得响应,所以问题是崩溃。当用户移回该特定屏幕时,可以说我有列表屏幕,其中我正在获取数据,这需要 6-7 秒,同时用户移回上一个屏幕,当数据来自 API 并将该删除回调到列表屏幕但用户移回该屏幕然后应用程序崩溃 下面是获取数据调用的代码。

+ (void) getRequestForDocumentListing:(NSDictionary *)headerParams urlQuery: (NSString*)action parameters:(NSDictionary*)params
                       onComplete:(void (^)(id json, id code))successBlock
                          onError:(void (^)(id error, id code))errorBlock
{
    NSString *authorizationValue = [self setAuthorizationValue:action];
    NSString *selectedLanguage = [ApplicationBaseViewController getDataFromDefaults:@"GLOBALLOCALE"];
    NSString *language = selectedLanguage;

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];

//set headers values
[manager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Accept"];
[manager.requestSerializer setValue:language forHTTPHeaderField:@"Accept-Language"];
[manager.requestSerializer setValue:authorizationValue forHTTPHeaderField:@"authorization"];
[manager.requestSerializer setValue:@"x-folder" forHTTPHeaderField:@"inbox"];
[manager GET:action parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
    NSLog(@"document listing success");

    NSInteger statusCode = [operation.response statusCode];
    NSNumber *statusObject = [NSNumber numberWithInteger:statusCode];

    successBlock(responseObject, statusObject);
}
     failure:^(AFHTTPRequestOperation *operation, NSError *error)
 {
     NSInteger statusCode = [operation.response statusCode];
     NSNumber *statusObject = [NSNumber numberWithInteger:statusCode];

     id responseObject = operation.responseData;
     id json = nil;
     id errorMessage = nil;

     if (responseObject) {

         json = [NSJSONSerialization JSONObjectWithData:responseObject options:kNilOptions error:&error];
         errorMessage = [(NSDictionary*)json objectForKey:@"Message"];
     }else{
         json = [error.userInfo objectForKey:NSLocalizedDescriptionKey];
         errorMessage = json;
     }

     errorBlock(errorMessage, statusObject);
 }];
}

我需要在 ViewdidDisappear 视图委托中停止调用

- (AFHTTPRequestOperation *)GET:(NSString *)URLString
                 parameters:(id)parameters
                    success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
                    failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
{
    AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithHTTPMethod:@"GET" URLString:URLString parameters:parameters success:success failure:failure];
    [self.operationQueue addOperation:operation];

    return operation;
}

如何解决这个特殊问题?

【问题讨论】:

  • 在数组中添加所有操作,并在 ViewdidDisappear 中循环遍历数组后停止。
  • @MOHAMMADISHAQ 你认为这是最好的方法吗,可能需要其他操作并且也很重要。
  • 您的应用程序正在崩溃,因为当您返回时,您的视图控制器被释放并且后台操作接近该释放的对象。因此,您需要删除/停止该视图控制器的所有正在进行的操作。如果您想继续重要不要停止,请选择一个共享数据模型,该模型会在成功时获得响应并更新视图控制器(如果未发布)

标签: ios objective-c xcode api afnetworking


【解决方案1】:

我明白你的意思,我认为问题不在于 AFNetWorking 或下载,而在于您如何组织视图控制器。
简而言之,您需要确保数据同步和查看。
导致您崩溃的原因是当用户执行某些操作(例如删除、移动...)时,数据与视图显示的数据不同。

让我们回放一个例子:
一个包含 12 个对象的数组,并以表格视图显示。
用户调用 Web 请求来更改数组。众所周知,这需要时间。
用户离开并再次回来。在此视图中,表格视图显示旧数组。
此时,Web 请求返回。数组被修改为10个对象。但是此时回调不会导致表格视图加载新数据。
当用户进行一些操作时,就像删除表视图中的第 11 个对象一样。实际上,数组中没有第 11 个对象。
所以崩溃来了。

如何处理是保持数据和视图的同步。

【讨论】:

    【解决方案2】:

    首先通过

    获取Operation对象的引用
    AFHTTPRequestOperation *operation = [manager GET:action parameters:nil success:^...blah blah blah...];
    

    然后,您可以在离开此屏幕时将完成块设置为零。

    [operation setCompletionBlock:nil];
    

    请注意,即使您离开屏幕,请求实际上也可能会成功执行。不过,您的应用现在不会崩溃。

    【讨论】:

      【解决方案3】:

      感谢 RuchiraRandana 和 childrenOurFuture 的回答,我从你的回答中得到了帮助,最后我找到了解决方案,我不会取消操作并设置 nil 委托,因为我的其他操作也在工作中,这是在其他屏幕上触发的.

      我只创建了一个 BOOL 并在单例类中设置了 YES 默认值,并且还在该特定类的 - (void)dealloc 中设置为 no,在我触发该委托的 API 类中我添加了该检查。

      if ([SHAppSingleton sharedInstance].isDocListControllerPop == YES) {
               [delegate documentListResponse:documentList andStatusCode:code];
           }
      

      我知道这可能不是完美的解决方案,但这解决了我的问题。 谢谢

      【讨论】:

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