ios - CGDataProviderCopyData builds up in memory causing crash -


okay, i'm downloading bunch of large-ish images (5mb) server in pieces, stitching pieces , rendering total image byte array. however, i've realized data each image not being released, , consequently builds causing memory warning , crash of app. thought because of explicit (__bridge_transfer nsdata *) casting arc take care of releasing object, it's still proving problem. in instruments, objects called "cgdataprovidercopydata" of ~ 1mb build , not discarded each file being stitched whole image. ideas or can steer me in right direction? obliged.

 // create  array add files total image nsmutablearray *bytearray = [[nsmutablearray alloc] initwithcapacity:(imageheight * imagewidth)];  // iterate through each file in files array (nsstring *file in array) {             // set baseurl individual file path     nsstring *baseurl = [nsstring stringwithformat:@"http://xx.225.xxx.xxx%@",[imageinfo objectforkey:@"baseurl"]];      // specify imagepath appending baseurl file name     nsstring *imagepath = [nsstring stringwithformat:@"%@%@", baseurl, file];      // change nsstring --> nsurl --> nsdata     nsurl *imageurl = [nsurl urlwithstring:imagepath];     nsdata *imagedata = [nsdata datawithcontentsofurl:imageurl];      // create image imagedata     uiimage *image = [uiimage imagewithdata:imagedata];     cgimageref cgimage = image.cgimage;      size_t width  = cgimagegetwidth(cgimage);     size_t height = cgimagegetheight(cgimage);      size_t bpr = cgimagegetbytesperrow(cgimage);     size_t bpp = cgimagegetbitsperpixel(cgimage);     size_t bpc = cgimagegetbitspercomponent(cgimage);     size_t bytes_per_pixel = bpp / bpc;      // cgdataproviderref cgimage     cgdataproviderref provider = cgimagegetdataprovider(cgimage);      // object not being released     nsdata *data = (__bridge_transfer nsdata *)cgdataprovidercopydata(provider);      //using (__bridge_transfer nsdata *) casts provider type nsdata , gives ownership arc, still not discarded      const uint8 *bytes = (byte *)[data bytes];      // log file being iterated through      nslog(@"---stitching png file total image: %@", file);      // populate byte array channel data each pixel     for(size_t row = 0; row < height; row++)     {         for(size_t col = 0; col < width; col++)         {             const uint8* pixel =             &bytes[row * bpr + col * bytes_per_pixel];              for(unsigned short = 0; < 4; i+=4)             {                 __unused unsigned short red = pixel[i];         // red channel - unused                 unsigned short green = pixel[i+1];              // green channel                 unsigned short blue = pixel[i+2];               // blue channel                 __unused unsigned short alpha = pixel[i+3];     // alpha channel - unused                  // create dicom intensity value intensity = [(g *250) + b]                 unsigned short dicomint = ((green * 256) + blue);                  //convert unsigned short intensity value nsnumber can store in array object                 nsnumber *dicomvalue = [nsnumber numberwithint:dicomint];                  // add image array (total image)                 [bytearray addobject:dicomvalue];             }         }     }     data = nil; } return bytearray; 

running "analyze" through xcode doesn't show apparent leaks either.

i took code, verbatim, , did more investigation. cfdataref/nsdata, able see problem seeing nsdatas not going away, , able solve wrapping portion of code uses nsdata in @autoreleasepool scope, this:

 // create  array add files total image nsmutablearray *bytearray = [[nsmutablearray alloc] initwithcapacity:(imageheight * imagewidth)];  // iterate through each file in files array (nsstring *file in array) {             // set baseurl individual file path     nsstring *baseurl = [nsstring stringwithformat:@"http://xx.225.xxx.xxx%@",[imageinfo objectforkey:@"baseurl"]];      // specify imagepath appending baseurl file name     nsstring *imagepath = [nsstring stringwithformat:@"%@%@", baseurl, file];      // change nsstring --> nsurl --> nsdata     nsurl *imageurl = [nsurl urlwithstring:imagepath];     nsdata *imagedata = [nsdata datawithcontentsofurl:imageurl];      // create image imagedata     uiimage *image = [uiimage imagewithdata:imagedata];     cgimageref cgimage = image.cgimage;      size_t width  = cgimagegetwidth(cgimage);     size_t height = cgimagegetheight(cgimage);      size_t bpr = cgimagegetbytesperrow(cgimage);     size_t bpp = cgimagegetbitsperpixel(cgimage);     size_t bpc = cgimagegetbitspercomponent(cgimage);     size_t bytes_per_pixel = bpp / bpc;      // cgdataproviderref cgimage     cgdataproviderref provider = cgimagegetdataprovider(cgimage);      @autoreleasepool     {         // object not being released         nsdata *data = (__bridge_transfer nsdata *)cgdataprovidercopydata(provider);      //using (__bridge_transfer nsdata *) casts provider type nsdata , gives ownership arc, still not discarded          const uint8 *bytes = (byte *)[data bytes];          // log file being iterated through          nslog(@"---stitching png file total image: %@", file);          // populate byte array channel data each pixel         for(size_t row = 0; row < height; row++)         {             for(size_t col = 0; col < width; col++)             {                 const uint8* pixel =                 &bytes[row * bpr + col * bytes_per_pixel];                  for(unsigned short = 0; < 4; i+=4)                 {                     __unused unsigned short red = pixel[i];         // red channel - unused                     unsigned short green = pixel[i+1];              // green channel                     unsigned short blue = pixel[i+2];               // blue channel                     __unused unsigned short alpha = pixel[i+3];     // alpha channel - unused                      // create dicom intensity value intensity = [(g *250) + b]                     unsigned short dicomint = ((green * 256) + blue);                      //convert unsigned short intensity value nsnumber can store in array object                     nsnumber *dicomvalue = [nsnumber numberwithint:dicomint];                      // add image array (total image)                     [bytearray addobject:dicomvalue];                 }             }         }         data = nil;     } } return bytearray; 

after adding @autoreleasepool, commented out part create nsnumbers , put them in array, , able see in allocations template of instruments indeed cfdata objects being released each turn of loop.

the reason commented out part create nsnumbers , put them in array, code in there, you're going end adding width * height * 4 nsnumbers bytearray. means if nsdata being released properly, heap use going width * height * 4 * <at least 4 bytes, maybe more> no matter what. maybe that's need do, sure made harder me see going on nsdatas because size being dwarfed array of nsnumbers.

hope helps.


Comments

Popular posts from this blog

Using django-mptt to get only the categories that have items -

wordpress - (T_ENDFOREACH) php error -

Export Excel workseet into txt file using vba - (text and numbers with formulas) -