NSMutableArray replaceObjectAtIndex: withObject Loop Leakage

I edited the previous post with some working code for convenience.

The following code (ARC'ed) seems to be leaking and working for a short period of time:

#define kROWS 100 #define kCols 34 void run(); static ViewController *instance; @interface ViewController () @property (nonatomic, strong) NSMutableArray *nsBackColor; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. self.nsBackColor = [NSMutableArray arrayWithCapacity:1]; instance = self; // set up a '2D array' for (int x = 0; x < kROWS; x++) { [self.nsBackColor addObject:[NSMutableArray arrayWithCapacity:1]]; for (int y = 0; y < kCols; y++) { [[self.nsBackColor objectAtIndex:x] addObject:[UIColor whiteColor]]; } } dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ run(); }); } - (void)plotColor:(UIColor *)color atX:(short)x andY:(short)y { [[self.nsBackColor objectAtIndex:x] replaceObjectAtIndex:y withObject:color]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end void plot(short xLoc, short yLoc, short backRed, short backGreen, short backBlue) { @autoreleasepool { [instance plotColor:[UIColor colorWithRed:((float)backRed/100) green:((float)backGreen/100) blue:((float)backBlue/100) alpha:(float)1] atX:xLoc andY:yLoc]; } } void run() { short x = 0; short y = 0; short backRed = 0; short backGreen = 0; short backBlue = 0; while (true) { x++; if (x >= kROWS) { x = 0; } y++; if (y >= kCols) { y = 0; } backRed = arc4random() % 255; backBlue = arc4random() % 255; backGreen = arc4random() % 255; plot(x, y, backRed, backGreen, backBlue); usleep(1000); } } 

If I let this run on the device or the simulator for a long time (a couple of minutes), I will receive either a malloc mmm (sim) error or a warning (device) of memory and a failure.

The transition between the selection tools I see + [UIColor colorWithRed: green: blue: alpha:] begin to act until, finally, hit the memory wall.

I can assign a UIColor property (directly or by making a copy), say self.myColor = color, and there is no leak.

I can do this too:

 [[self.nsBackColor objectAtIndex:x] replaceObjectAtIndex:y withObject:[self description]]; 

and I get the same leaks.

It seems to me that the object is replaced in an array (and yes, it originally started as a 2D c array, but I thought it was a problem) was forever lost and leaked and was not properly released.

These will be Tools-> Selection after launch for a short period of time:

Instruments

Any help would be greatly appreciated and additional information could be provided.

+4
source share
1 answer

What happens is that you create an autostart pool at each iteration. Thus, the following line is launched each time with a new autostart pool:

 [[self.nsBackColor objectAtIndex:x] replaceObjectAtIndex:y withObject:color]; 

Therefore, color increases the reference counter in the local pool by one, and [[self.nsBackColor objectAtIndex:x] objectAtIndex:y] decreases the reference counter in the local pool by one. But here's the catch: this element was color in the previous iteration, in which its reference count was controlled by the previous pool that you released / released earlier.

So, what was to happen, since the previous pool was released at the previous iteration, this object was released. His reference count was 2 (one for [UIColor colorWith...] , one for adding to the array), so he should have received 2 release messages as soon as the pool was drained and the pointer in [[self.nsBackColor objectAtIndex:x] objectAtIndex:y] should be left hanging [[self.nsBackColor objectAtIndex:x] objectAtIndex:y] until you replace it in the current iteration with a pointer to color .

Clearly, this is not how it should be, or as I understand it. However, the @autoreleasepool {} directive is clearly inappropriate. It should be around the while (true) or removed altogether in favor of the thread pool.

0
source

All Articles