Reputation: 4221
I'm sending a lot of image files via AfNetworking to a Rails server. On edge and sometimes 3G I get this error: Error Domain=NSPOSIXErrorDomain Code=12 "The operation couldn’t be completed. Cannot allocate memory".
This is the code I'm using to send the files: https://gist.github.com/cc5482059ae3023bdf50
Is there a way to fix this?
Online some people suggest that a workaround would be to stream the files. I haven't been able to find a tutorial about streaming multiple files using AFNetworking. How can I do this?
Upvotes: 3
Views: 2432
Reputation: 266
I know it's been a while since this question was asked but I just have to give my two cents on the matter.
After spending the better part of the week trying to figure this stuff out here's where I'm at right now:
Might be because of faulty networking by the phone hardware itself or might be about the need to throttle the bandwidth (or just a bug in NSURLConnection):
http://aws.amazon.com/articles/0006282245644577
https://forums.dropbox.com/topic.php?id=25351
POSIX error 12 ("Cannot allocate memory") while uploading files from an iPhone
I would have moved to ASIHTTPRequest but it is no longer maintained, so it's now worth implementing. Maybe I should still try AFNetworking, but I'm really starting to think this is an issue which has been fixed in the iOS already (or may be a shoddy iPhone in my case).
But I cannot for the life of me find a simple explanation for this.
Upvotes: 0
Reputation: 4870
How big are the images? And how many are you trying to send?
I can't seem to find an easy way to implement an NSInputStream
using AFNetworking
, but there's definitely one thing you should try, which is avoiding putting big objects in the autorelease pool. When you are creating big NSData instances insinde a for loop, and those are going to the autorelease pool, all that memory sticks around for as long as the loop lasts. This is one way to optimize it:
for (int i=0; i<[self.sImages count]; i++) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSData *imageData = UIImageJPEGRepresentation([self.sImages objectAtIndex:i], 0.7);
[formData appendPartWithFileData:imageData name:@"pics[]" fileName:@"avatar.jpg" mimeType:@"image/jpeg"];
pool drain];
}
Or, if you're using LLVM3:
for (int i=0; i<[self.sImages count]; i++) {
@autoreleasepool {
NSData *imageData = UIImageJPEGRepresentation([self.sImages objectAtIndex:i], 0.7);
[formData appendPartWithFileData:imageData name:@"pics[]" fileName:@"avatar.jpg" mimeType:@"image/jpeg"];
}
}
Upvotes: 1