objective c - Should NSPurgeableData be reusable after its contents have been discarded? -
i have code using nspurgeabledata
working, until machine's memory usage started running high, @ point started exception thrown. message in exception:
*** terminating app due uncaught exception 'nsgenericexception', reason: '*** -[nspurgeabledata length]: accessed outside successful -begincontentaccess , -endcontentaccess calls.'
this essence of code:
- (nsimage *)imageproperty { if (!self.purgeableimage || ![self.purgeableimage begincontentaccess]) { if (!self.purgeableimage) { self.purgeableimage = [nspurgeabledata data]; } nsimage *image = // image // line causes exception [self.purgeableimage setdata: image.tiffrepresentation]; } } - (void)clearimage { [self.purgeableimage endcontentaccess]; // putting in line works, shouldn't necessary, should it? //self.purgeableimage = nil }
clearimage
balanced calls imageproperty. i'm able reproduce exception test case:
- (void)testimageproperty_calltwicewithmemorypressure { myclass *instance = // initialize sucker nsimage *image = instance.imageproperty; nspurgeabledata *purgeabledata = image.purgeableimage; xctassertnotnil(image, @"image not loaded"); xctassertequal(image.size.width, (cgfloat)988, @"image loaded incorrect width"); xctassertequal(image.size.height, (cgfloat)1500, @"image loaded incorrect height"); [instance clearimage]; // discard, if there memory pressure [purgeabledata discardcontentifpossible]; xctasserttrue(purgeabledata.iscontentdiscarded, @"failed simulate memory pressure"); // triggers exception image = instance.imageproperty; xctassertnotnil(image, @"image not loaded on second attempt"); }
i can eliminate exception uncommenting second line in -clearimage
, didn't think necessary. shouldn't able continue using nspurgeabledata
object after original data has been discarded?
update: additional workaround
the problem nilling out after calling -endcontentaccess
class provides no caching. solution found update leading if
statements so:
if (!self.purgeableimage || self.purgeableimage.iscontentdiscarded || ![self.purgeableimage begincontentaccess]) { if (!self.purgeableimage || self.purgeableimage.iscontentdiscarded) {
Comments
Post a Comment