2016-02-19 66 views
0

這段代碼爲什麼會產生泄漏?它怎麼能解決?目標C塊內的塊產生泄漏。我該如何解決它?

這是原始呼叫:

NSString * url = @"https://theserverurl/user/login" ; 
NSDictionary *parameters = @{@"login":@"[email protected]", @"password":@"encrypted-password"} ; 


[[BackEndAPI sharedManager] NSURLSessionOperation: @"POST" url: url parameters: parameters success:^(NSURLRequest *request, NSHTTPURLResponse * response, id responseObject) { 
    // Success 
} failure:^(IDLEngineError *engineError) { 
    // Failure   
}] ; 

這是處理NSURL要求單身:

- (NSMutableURLRequest *) NSURLSessionOperation:(NSString *) restOperation 
              url:(NSString *)url 
             parameters:(id)parameters 
             success:(void (^)(NSMutableURLRequest *request, NSHTTPURLResponse * response, id responseObject))success 
             failure:(void (^)(IDLEngineError *))failure { 


    NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration]; 

    __weak id weakSelf = self ; 

    // POST 
    if ([restOperation isEqualToString:@"POST"]) { 

     NSError *error; 
     NSURLSession *session = [NSURLSession sessionWithConfiguration: sessionConfig ]; 

     // Create the request 
     __block NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL: [NSURL URLWithString: url ] ]; 
     [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"] ; 
     request.HTTPMethod = @"POST"; 
     NSData *postData = [NSJSONSerialization dataWithJSONObject: parameters options: 0 error:&error]; 
     [request setHTTPBody:postData]; 

     // Perform operation 
     NSURLSessionDataTask * task = [session dataTaskWithRequest: request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 

      // This generates a leak!!!! 
      success(request, nil, nil) ; 

     }] ; 

     [task resume] ; 

    } 


    return nil ; 


} 

請看看到GitHub上泄露的應用:

https://github.com/arkyxperience/myleakedapp

在此處查找報告(屏幕截圖)comin克從儀器:

Result of Instruments - Leaks

+1

1.不需要__block,這是肯定的。 2.你確定成功塊中沒有任何東西會導致泄漏嗎? 3.請仔細檢查您的「簡化」是否沒有刪除重要的代碼。 –

+0

成功塊應該是直截了當的,不知道這是否是問題所在。我已經將應用程序上傳到GitHub,所以您可以看到簡化沒有刪除有問題的代碼片段,因爲泄漏仍然存在。 – RGML

回答

0

原來的泄漏與NSURLSessionDataTask。如果你隔離下面的一段代碼,泄漏將保持:

NSString * url = @"https://theserverurl/user/login" ; 
NSDictionary *parameters = @{@"login":@"[email protected]", @"password":@"encrypted-password"} ; 

NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration]; 

NSError *error; 
NSURLSession *session = [NSURLSession sessionWithConfiguration: sessionConfig ]; 


// Create the request 
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL: [NSURL URLWithString: url ] ]; 
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"] ; 
request.HTTPMethod = @"POST"; 
NSData *postData = [NSJSONSerialization dataWithJSONObject: parameters options: 0 error:&error]; 
[request setHTTPBody:postData]; 

// Perform operation 
NSURLSessionDataTask * task = [session dataTaskWithRequest: request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 

}] ; 

[task resume] ; 

我做錯了什麼?

+0

嘗試刪除越來越多的代碼,在某些時候它會停止泄漏,然後告訴線 – markov

+0

泄漏在這裏:「NSURLSessionDataTask * task = ...」它看起來像庫泄漏。如果你不執行任務,泄漏消失。 – RGML

+0

你的意思是沒有'[任務恢復];'? – markov

0

好吧,我試過你的github代碼,看起來好像沒有泄漏。畢竟什麼東西在泄漏?要測試此代碼,請將恢復ID添加到您的控制器。在這個代碼中,即使我不使用弱調用控制器,也會觸發dealloc。所以控制器沒有泄漏,完整的塊沒有保留循環。在NSURLSessionOperation:中沒有看到任何可能泄漏的東西。那麼泄漏到底是什麼?

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    NSString * url = @"https://google.com" ; 
    NSDictionary *parameters = @{@"login":@"[email protected]", @"password":@"encrypted-password"} ; 
    [[BackEndAPI sharedManager] NSURLSessionOperation: @"POST" url: url parameters: parameters success:^(NSURLRequest *request, NSHTTPURLResponse * response, id responseObject) { 
     NSLog(@"finish"); 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      self.view.window.rootViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"ViewController"]; 
     }); 

    } failure:^(NSError * error) { 
     NSLog(@"fail"); 
    }]; 
} 

- (void)dealloc { 
    NSLog(@"Did dealloc"); 
} 
+0

我不知道什麼泄漏,但控制器仍然可以調用dealloc並泄漏。使用儀器 - 泄漏,你會看到如何調用該塊產生泄漏與您的代碼。您將從我從樂器提供的截圖中獲得相同的輸出。 – RGML

相關問題