取消之前的 AFHTTPSessionManager 请求

Cancel previous request of AFHTTPSessionManager

我有一个文本字段,每当用户输入字符时,我都会将该字符附加到我的 url 并获得响应。 我需要取消之前的请求。 例如,如果我输入 "shampoo" 我将访问服务器 7 次,我需要取消最后 6 个请求。 目前我正在使用 [manager.operationQueue cancelAllOperations]; 但是有些方法对我不起作用。可能是我没放对吧。

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string;
{


    //[self.s_searchResultText setHidden:YES];
    // [SVProgressHUD dismiss];

    [self.s_tableView setHidden:true];
    [searchProductArray removeAllObjects];
    [self.s_tableView reloadData];

    NSCharacterSet *cs = [[NSCharacterSet characterSetWithCharactersInString:UNACCEPTABLE_CHARACTERS] invertedSet];
    NSLog(@"%@",cs);

    NSString *filtered = [[string componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:@""];
    NSLog(@"%@",filtered);

    NSLog(@"%lu",(unsigned long)filtered.length);

    if (filtered.length) {
        [CustomToastAlert showToastInParentView:self.view withText:@"Please enter valid characters" withDuaration:1.5];
        return NO;
    }


    searchTextString = [textField.text stringByAppendingString:string];
    NSLog(@"%lu",(unsigned long)[searchTextString length]);


    NSLog(@"%@",searchTextString);
    int stringLength=[searchTextString length];
    const char * _char = [string cStringUsingEncoding:NSUTF8StringEncoding];
    int isBackSpace = strcmp(_char, "\b");

    if (isBackSpace == -8) {
        stringLength=[searchTextString length];
        stringLength=[searchTextString length]-1;
        searchTextString=[searchTextString substringToIndex:stringLength];
        NSLog(@"Backspace was pressed");
        NSLog(@"string is %@",searchTextString);
    }



    if(stringLength>=3)
    {
        AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] init];
        manager.responseSerializer = [AFJSONResponseSerializer serializer];
        NSString *urlString=[NSString stringWithFormat:kSearchProductUrl,kBaseUrl];

        urlString = [urlString stringByAppendingString:searchTextString];
        urlString = [urlString stringByReplacingOccurrencesOfString:@" " withString:@"%20"];

        NSLog(@"%@",searchTextString);
        NSLog(@"%@",urlString);
        [searchProductArray removeAllObjects];
       // [manager invalidateSessionCancelingTasks:NO];
        //[manager.operationQueue cancelAllOperations];


        [manager GET:urlString parameters:nil success:^(NSURLSessionDataTask *task, id responseObject)
         {
             [searchProductArray removeAllObjects];

             //[SVProgressHUD showWithStatus:LOADING_ITEMS maskType:SVProgressHUDMaskTypeGradient];
             NSLog(@"JSON: %@", responseObject);
             json= responseObject;
             NSLog(@"%@",json);
             NSLog(@"%lu",(unsigned long)[[json valueForKeyPath:@"data"] count ]);

             for(int i=0;i<[[json valueForKeyPath:@"data"]count ];i++)
             {
                 Product *s_productList=[[Product alloc]init];
                 s_productList.SKU_Name=[[json valueForKeyPath:@"data.sku_name"]objectAtIndex:i];
                 s_productList.SKU_Id=[[json valueForKeyPath:@"data.sku_id"]objectAtIndex:i];
                 s_productList.SKU_Price=[[json valueForKeyPath:@"data.sku_price"]objectAtIndex:i];
                 s_productList.SKU_OfferPrice=[[json valueForKeyPath:@"data.sku_offer_price"]objectAtIndex:i];

                 s_productList.SKU_Currency = RUPEE_SYMBOL;
                 s_productList.SKU_AvailableUnit=[[json valueForKeyPath:@"data.sku_available_unit"]objectAtIndex:i];
                 s_productList.SKU_OfferDescription= [[json valueForKeyPath:@"data.sku_offer_desc"]objectAtIndex:i];
                 s_productList.SKU_ImageUrls=[[json valueForKeyPath:@"data.sku_image_urls"]objectAtIndex:i];


                 [searchProductArray addObject:s_productList];
                 NSLog(@"%lu",(unsigned long)[searchProductArray count]);


             }
             [self.s_tableView setHidden:FALSE];
             [self.s_tableView reloadData];
             NSLog(@"%lu",(unsigned long)[searchProductArray count]);
             if ([searchProductArray count]==0) {
                 [CustomToastAlert showToastInParentView:self.view withText:SEARCH_RESULT withDuaration:1.5];



             }


         }

             failure:^(NSURLSessionDataTask *task, NSError *error)
         {
             [CustomToastAlert showToastInParentView:self.view withText:NO_DATA_AVAIL withDuaration:1.5];
         }];


    }

    return YES;

}

我不确定您的 class 是如何工作的,但我注意到每次 textField 文本更改时您都在初始化一个新的 AFHTTPSessionManager 对象

所以这是我对这个问题的建议。

// somewhere in your class, let's say in ViewDidLoad you should init the AFHTTPSessionManager object
- (void)viewDidLoad {
    [super viewDidLoad];

    /// create the AFHTTPSessionManager object, we're gonna use it in every request
    self.manager = [[AFHTTPSessionManager alloc] init];
    self.manager.responseSerializer = [AFJSONResponseSerializer serializer];

    /// create an array that is going to hold the requests task we've sent to the server. so we can get back to them later
    self.arrayOfTasks = [NSMutableArray new];
    /// discussion:
    /// an array holds multiple objects. if you just want to hold a ref to the latest task object
    /// then create a property of NSURLSessionDataTask instead of NSMutableArray, and let it point to the latest NSURLSessionDataTask object you create

}



-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string;{
    /// your code goes here
    /// .....
    /// .....
    /// .....
    /// .....
    /// till we reach
    if(stringLength>=3){
        /// cancel all previous tasks
        [self.arrayOfTasks enumerateObjectsUsingBlock:^(NSURLSessionDataTask *taskObj, NSUInteger idx, BOOL *stop) {
            [taskObj cancel]; /// when sending cancel to the task failure: block is going to be called
        }];

        /// empty the arraOfTasks
        [self.arrayOfTasks removeAllObjects];

        /// init new task
        NSURLSessionDataTask *task = [self.manager GET:urlString parameters:nil success:^(NSURLSessionDataTask *task, id responseObject){
           /// your code
        }failure:^(NSURLSessionDataTask *task, NSError *error){
           /// your code
        }];

        /// add the task to our arrayOfTasks
        [self.arrayOfTasks addObject:task];
    }
    return YES;
}