Note that there are some explanatory texts on larger screens.

plurals
  1. POAllocated data of NSMutableRequest object's body not being released
    text
    copied!<p>In my app I have to perform a multipart POST request. In the request I have to send a file that is stored in the device's photo Library. After it is finished uploading and received the returned data, I send the request a release message, but Instruments shows me the data persists in the device's memory. </p> <p>This is how I create the request object:</p> <pre><code>NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init]; [request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData]; [request setHTTPShouldHandleCookies:YES]; [request setTimeoutInterval:30]; [request setHTTPMethod:@"POST"]; NSString *boundary = @"---------------------------14737809831466499882746641449"; // set Content-Type in HTTP header NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary]; [request setValue:contentType forHTTPHeaderField: @"Content-Type"]; // post body NSMutableData *body = [[NSMutableData alloc] init]; // add parts (all parts are strings) `parts` is a NSDictionary object for(id key in parts) { [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", key] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[[NSString stringWithFormat:@"%@\r\n", [parts objectForKey:key]] dataUsingEncoding:NSUTF8StringEncoding]]; } // add files data - `file` is a ALAssetRepresentation object NSData *fileData; NSString *filename = [file filename]; Byte *buffer = (Byte*)malloc(file.size); NSUInteger buffered = [file getBytes:buffer fromOffset:0.0 length:file.size error:nil]; fileData = [[NSData alloc] initWithBytesNoCopy:buffer length:buffered freeWhenDone:YES]; if (fileData) { [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; if ([requestType isEqualToString:PUBLISH_TYPE_VC_MANDA]) { [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"attachment\"; filename=\"%@\"\r\n", filename] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[@"Content-Type: image/jpeg\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; } else { [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"file\"; filename=\"%@\"\r\n", filename] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[@"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; } [body appendData:fileData]; [body appendData:[[NSString stringWithFormat:@"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]]; } [fileData release]; [body appendData:[[NSString stringWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; // setting the body of the post to the reqeust [request setHTTPBody:body]; [body release]; // set the content-length NSString *postLength = [NSString stringWithFormat:@"%d", [body length]]; [request setValue:postLength forHTTPHeaderField:@"Content-Length"]; [request setValue:@"Keep-Alive" forHTTPHeaderField:@"Connection"]; // set URL `adress` is a NSURL object [request setURL:address]; //set cookie if (storedCookie) { NSDictionary *properties = [NSDictionary dictionaryWithObjectsAndKeys:[storedCookie name], NSHTTPCookieName, myDomain, NSHTTPCookieDomain,@"/",NSHTTPCookiePath, [storedCookie value], NSHTTPCookieValue, nil]; NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:properties]; NSArray* cookies = [NSArray arrayWithObjects: cookie, nil]; NSDictionary * headers = [NSHTTPCookie requestHeaderFieldsWithCookies:cookies]; [request setAllHTTPHeaderFields:headers]; } </code></pre> <p>After this, and after I received the response, i perform <code>[request release]</code> but the allocated bytes stay in memory.</p> <p>I ran <code>Instruments</code> in the Allocations mode, and it is claiming that there is an object of category <code>Malloc 91MB</code> (the size of the ALAsset I'm uploading). By looking at the Call tree, the Symbol that's taking up all the memory is <code>[NSConcreteMutableData appendBytes:length:]</code> inside the method described above.</p> <p>Why isn't it freeing the bytes ? And more importantly, why does it have to move the data to the device's memory ? I've seen apps like Facebook upload very large videos from the gallery without any memory problems.</p> <p>Thank you very much for your attention, any help or directions would be greatly appreciated</p> <p><strong>EDIT:</strong> Further investigation showed me that when I use <code>[request release]</code> the request object is released, but it's body isn't. Pretty weird behaviour...</p> <p><strong>EDIT2:</strong> I explicitly used <code>[request.HTTPBody release];</code> and the bytes were released. I still cannot believe that <code>[request release]</code> wasn't freeing it's body. Could this be a bug ?</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload