2016-01-13 1 views
0

У меня есть класс под названием RequestController, который отвечает за загрузку, разбор данных и помещает их в массив свойств, доступный из родителя.Инициализация пользовательского класса с iVar, вызывающим утечку памяти - iOS

Проблема заключается в том, что метод, инициализирующий RequestController, выполняется более одного раза и с использованием Allocations я заметил, что это происходит с утечкой памяти и объектами, которые никогда не выпускаются. Переменная RequestController - это iVar. Кроме того, RequestController возвращает делегата родительскому контроллеру.

RequestController.h

#import <Foundation/Foundation.h> 

//================ 

@protocol RequestControllerDelegate <NSObject> 

@required 
- (void)RequestControllerRequestSuccessful:(NSInteger)mode; 
- (void)RequestControllerRequestFailedWithError:(NSInteger)code; 

@end 

//================= 

@interface RequestController : NSObject <NSURLSessionDataDelegate> 

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

@property(nonatomic,strong)NSMutableArray *resultArray; 
@property(nonatomic,strong)NSMutableArray *purposesArray; 

-(instancetype)initAndRegisterUserWithTelephone:(NSString*)tel Delegate:(id<RequestControllerDelegate>)del; 
-(void)nulifyArrays; 

@end 

Инициализация объекта в RequestController.m

@implementation RequestController{ 

     NSURLSession *conn; 
     NSArray *responseArray; 
     NSMutableData *responseData; 
     NSString *reqEmail; 

} 
@synthesize delegate,resultArray; 

#pragma mark - Init Functions 
-(instancetype)initAndRegisterUserWithTelephone:(NSString*)tel Delegate:(id<RequestControllerDelegate>)del{ 



    self = [super init]; 

    if (self) { 

     currentMode=RQRegisterMode; 

     self.delegate=del; 

     //Check for internet connection 
     bool internet = [self internetConnectivity]; 

     //Sending the requests on the server 
     if(internet){ 

      NSString* url = [NSString stringWithFormat:@"%@/someurlwithparams",API_URL]; 

      NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10]; 

      NSString *param= [NSString stringWithFormat:@"method=%@",tel]; 

      NSData *requestBodyData = [param dataUsingEncoding:NSUTF8StringEncoding]; 

      request.HTTPBody = requestBodyData; 

      // Specify that it will be a POST request 
      request.HTTPMethod = @"POST"; 


      NSURLSessionConfiguration *sessionConfig =[NSURLSessionConfiguration defaultSessionConfiguration]; 
      conn = [NSURLSession sessionWithConfiguration:sessionConfig delegate:self delegateQueue:[NSOperationQueue mainQueue]]; 

      NSURLSessionDataTask *dataTask= [conn dataTaskWithRequest:request]; 
      [dataTask resume]; 
     } 

     else 
     { 

      //No internet connection 
      [delegate RequestControllerRequestFailedWithError:RCNoInternetError]; 

     } 



    } 
    return self; 

} 

В родительском контроллере я инициализировать объект как:

req = [[RequestController alloc]initAndRegisterUserWithTelephone:fullTel Delegate:self]; 

И у меня есть эти делегаты:

-(void)RequestControllerRequestSuccessful:(NSInteger)mode{ 
    [SVProgressHUD dismiss]; 
    [self manageError:NoError]; 
    //Copying the data to local variable 
    self.array = [NSMutableArray alloc]initWithArray:[req resultArray]]; 

} 

-(void)RequestControllerRequestFailedWithError:(NSInteger)code{ 
    [SVProgressHUD dismiss]; 
    [self manageError:code]; 

} 

До сих пор так хорошо, но как только я инициализировать RequestController у меня есть утечка памяти. Что я здесь делаю неправильно?

Update 1 Эта линия вызывает утечку:

conn = [NSURLSession sessionWithConfiguration:sessionConfig delegate:self delegateQueue:[NSOperationQueue mainQueue]]; 

Update 2

Замена self с nil решает эту проблему, но мне нужны делегаты NSURLSession

ответ

0

Проблема заключалась в том, что я не признал недействительным NSURLSession, как только закончил задачу.

По Apple:

После аннулируется, ссылки на делегат и обратного вызова объектов являются сломана. После недействительности объекты сеанса нельзя использовать повторно.

Таким образом, я использовал [conn invalidateAndCancel] после завершения моей задачи в своих делегатах, и утечка исчезла.

-1

Попробуйте использовать: AFNetWorking

AFNetworking восхитительное сетевая библиотека для IOS и Mac OS X.

и Singleton, я думаю, что это лучший способ для обработки запроса к серверу.

это в RequestManager.h:

#import <Foundation/Foundation.h> 

@interface RequestManager : NSObject 

    + (RequestManager *)sharedClass; 

    - (void)registerUserWithTelephone:(NSString *)tel 
           success:(void(^)(BOOL finished, NSArray *JSONResponse))success; 

это в RequestManager.m:

#import "RequestManager.h" 
#import "AFNetworking.h" 

@implementation RequestManager 

static RequestManager *sharedClassInstance = nil; 

+ (RequestManager *) sharedClass { 
     @synchronized(self) { 
      if (!sharedClassInstance) 
       sharedClassInstance = [[RequestManager alloc] init]; 
      return sharedClassInstance; 
     } 
} 

- (void)registerUserWithTelephone:(NSString *)tel 
          success:(void(^)(BOOL finished, NSArray *JSONResponse))success{ 

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; 

manager.responseSerializer = [AFHTTPResponseSerializer serializer]; 
manager.requestSerializer = [AFHTTPRequestSerializer serializer]; 

NSString *URLString = @"URL STRING"; 

NSDictionary *parameters = @{@"PARAMETER NAME" : tel}; 

[manager POST:URLString parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) { 

    NSError *error = nil; 
    NSArray *data = [NSJSONSerialization JSONObjectWithData:responseObject 
                options:0 
                 error:&error]; 
    success(YES, data); 


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

    NSData *errorData = error.userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey]; 
    NSDictionary *serializedData = [NSJSONSerialization JSONObjectWithData:errorData options:kNilOptions error:nil]; 

    NSLog(@"RequestManager error code %ld",[operation.response statusCode]); 

}]; 

} 

Вы можете получить его в контроллере, как это:

#import "RequestManager.h" 

[[RequestManager sharedClass] registerUserWithTelephone:telNumberString 
           success:^(BOOL finished, NSDictionary *JSONResponse){ 

NSLog(@"%@", JSONResponse); 

}]; 

Это вид кода, который я использую в своем приложении.

+0

Спасибо за ваш ответ. Я знаю об AFNetworking, но мой вопрос касался решения проблемы с утечкой памяти. – BlackM

Смежные вопросы