AFURLSessionManager when my ViewController was nav

2019-07-28 02:49发布

问题:

I have problem in AFURLSessionManager for Objective-C iOS. I have 2 viewController and use AFURLSessionManager for getData from server.

when user navigate to viewContoller2 that have AFURLSessionManager request and user has very bad network and press back button, AFURLSessionManager want to call delegate, crashed and show EXC_BAD_ACCESS(code=EXC_I386_GPFLT)

when i navigate to a viewController, AFURLSessionManager task finish late and viewController was changed by user and AFURLSessionManager try call delegates not exists in MEMORY.

Anyone has any idea fix this problem?

This is request code :

- (void) getData
{
    NSMutableURLRequest *req = [[AFJSONRequestSerializer serializer] requestWithMethod:@"GET" URLString:@"http://----------" parameters:nil error:nil];

    AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];

    req.timeoutInterval= 15;
    [req setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    [req setValue:@"application/json" forHTTPHeaderField:@"Accept"];

    self.dataTask = [manager dataTaskWithRequest:req completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error)
     {

         if (!error)
         {
             NSLog(@"Reply JSON >>>>>> responseObject <<<<<: %@", responseObject);


             if ([responseObject isKindOfClass:[NSDictionary class]])
             {
                 if (self.delegate && [self.delegate respondsToSelector:@selector(success:)]) {
                     [self.delegate success:responseObject];
                 }
                 //                  self.colorView.backgroundColor = [UIColor blueColor];
                 return;
             }
             else
             {
                 NSLog(@"Error No dictionary: %@, %@, %@", error, response, responseObject);
                 {
                     //                      self.colorView.backgroundColor = [UIColor redColor];
                     [self.delegate error:error];
                     return;
                 }

             }
         }
         else
         {
             NSLog(@"Error: %@, %@, %@", error, response, responseObject);
             [self.delegate error:error];
             return;

         }

     }];

    [self.dataTask resume];

    if (self.cancelRequest) {
        [self.dataTask cancel];
    }
}

header file :

@protocol WebServicesDelegate <NSObject>

- (void) success:(NSDictionary *) dic;
- (void) error:(NSError *) error;

@end

@interface WebServices : NSObject

@property (assign,nonatomic) id<WebServicesDelegate> delegate;
@property (nonatomic) BOOL cancelRequest;

-(void) setCancelRequest:(BOOL)cancelRequest;
//+(instancetype) shareInstance;

- (void) getData;

@end

Thanks in advance

回答1:

Debug what self.delegate is. It is definitely not nil otherwise it wouldn't have crashed.

It crashed because self.delegate is not an NSObject subclass. It is either a scalar or some garbage value.

I guess you have used assign instead of weak while declaring delegate and because it is assigned, it is resulting in a dangling pointer.

EDIT(after question update) Change

@property (assign,nonatomic) id<WebServicesDelegate> delegate;

to

@property (weak,nonatomic) id<WebServicesDelegate> delegate;


回答2:

Issue may be with the self as your webservice is async so when the response comes you have already removed that viewcontroller by pop or dismiss

you should use __weak typeof(self) weakSelf = self;

and use weakSelf at the place of self

Hope it helps to solve your issue