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

wordpress - (T_ENDFOREACH) php error -

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

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