objective c - iOS selector crashes the App -


i created simple httpclient afnetworking.

httpclient *client = [[httpclient alloc] initwithtarget:(id)target                                                  before:(sel)before                                                 success:(sel)success                                                 failure:(sel)failure                                                 timeout:(sel)timeout] 

so controller can register callback function when perfroms http request. , here how wrote callback functions:

- (void)successmethod:(id)response {   //  logdebug(@"success: %@", response);   self.lock = false;   if (self.target == nil || self.successcallback == nil) {     return;   }   if ([self.target respondstoselector:self.successcallback]) {     [self.target performselector:self.successcallback withobject:response];   } } 

but here found problem. when request comes fast, works fine. if request comes after longtime , meanwhile, user changes view. crashes app , throw exception like, selector can not performed on nil object.

so want know whether did in right way , there way solve problem? best practices implement this?

=====

update:

sorry didn't put error log. there no information can get. sometime there no log. put screenshot here , hope can help.

i , there no exception log.

enter image description here

==== update

and hope can help

#import "httpclient.h" #import "afnetworking.h" #import "logging.h"  @interface httpclient ()  @property int retrycounter; @property(nonatomic) nsstring *action; @property(nonatomic) nsstring *url; @property(nonatomic) nsdictionary *param; @property(nonatomic) afhttprequestoperationmanager *manager;  @end  @implementation httpclient  - (id)initwithtarget:(id)target               before:(sel)before              success:(sel)success              failure:(sel)failure              timeout:(sel)timeout {   self = [super init];   if (self) {     self.target = target;     self.before = before;     self.success = success;     self.failure = failure;     self.timeout = timeout;     self.lock = false;     self.retrymaxcounter = 2;     self.retrycounter = 0;      self.manager = [afhttprequestoperationmanager manager];     self.manager.requestserializer = [afjsonrequestserializer serializer];     self.manager.responseserializer = [afjsonresponseserializer serializer];   }   return self; }  - (void)request:(nsstring *)action             url:(nsstring *)url           param:(nsdictionary *)param {   self.action = action;   self.url = url;   self.param = param;   [self beforemethod];   [self request]; }  - (void)request {   if (self.lock) {     return;   }   if ([[self.action lowercasestring] isequal:@"get"]) {     //     logdebug(@"send request.");     self.lock = true;     loginfo(@"%@\n%@", self.url, self.param);     [self.manager get:self.url         parameters:self.param         success:^(afhttprequestoperation *operation, id responseobject) {           [self successmethod:responseobject];         }         failure:^(afhttprequestoperation operation, nserror error) {           if ([operation.response statuscode] == 500) {             [self failuremethod:operation.responseobject];           } else {             [self timeoutmethod];           }         }];   } else if ([[self.action lowercasestring] isequal:@"post"]) {     // post     logdebug(@"send post request.");     self.lock = true;     loginfo(@"%@\n%@", self.url, self.param);     [self.manager post:self.url         parameters:self.param         success:^(afhttprequestoperation *operation, id responseobject) {           [self successmethod:responseobject];         }         failure:^(afhttprequestoperation operation, nserror error) {           if ([operation.response statuscode] == 500) {             [self failuremethod:operation.responseobject];           } else {             [self timeoutmethod];           }         }];   } else {     logerror(@"not supported request method.");   } }  #pragma clang diagnostic push #pragma clang diagnostic ignored "-warc-performselector-leaks"  - (void)beforemethod {   logdebug(@"before requesting.");   if (self.target == nil || self.before == nil) {     return;   }   if ([self.target respondstoselector:self.before]) {     [self.target performselector:self.before];   } }  - (void)successmethod:(id)success {   //  logdebug(@"success: %@", success);   self.lock = false;   if (self.target == nil || self.success == nil) {     return;   }   if ([self.target respondstoselector:self.success]) {     [self.target performselector:self.success withobject:success];   } }  - (void)failuremethod:(id)failure {   logdebug(@"failure: %@", failure);   self.lock = false;   if (self.target == nil || self.failure == nil) {     return;   }   if ([self.target respondstoselector:self.failure]) {     [self.target performselector:self.failure withobject:failure];   } }  - (void)timeoutmethod {   logerror(@"request timeout.");   self.lock = false;   self.retrycounter++;   if (self.retrycounter < self.retrymaxcounter) {     [self request];   } else {     if (self.target == nil || self.timeout == nil) {       return;     }     if ([self.target respondstoselector:self.timeout]) {       [self.target performselector:self.timeout];     }   } }  #pragma clang diagnostic pop  @end 

thank much!

==== update

i found problem. because set targe assign instead of weak. difference between assign , weak, please refer stackoverflow question

there not enough information problem. can guess possible reason.

i guess add target first request, works okay, when make second request, there 2 targets perform selector. first object released can't perform selector.

you have remove target not in use.


Comments

Popular posts from this blog

php - failed to open stream: HTTP request failed! HTTP/1.0 400 Bad Request -

java - How to filter a backspace keyboard input -

java - Show Soft Keyboard when EditText Appears -