Following this discussion, I’ve encountered a bad access issue;
A loop has several steps: a, b, c, … x, y, z:
-(void)cycle:(float)delta{
[self stepA]
[self stepB]
// etc.
[self stepZ]
}
At some point, step x does the following:
// IRQ is an NSMutableArray
// Self is a reference to the engine running the cycles
[IRQ addObject:^{ NSLog(@"hello! %@", self); } ];
Later, step z is to process all “delayed” calls:
for (int i = 0; i < [IRQ count]; i++){
void (^delayedCall)(void) = [IRQ objectAtIndex:i];
delayedCall();
}
[IRQ removeAllObjects];
Result: EXEC_BAD_ACCESS
Now, if step x only adds a plain string with no object reference like follows, step Z works fine:
[IRQ addObject:^{ NSLog(@"hello!"); } ];
Last observation, if a same step both adds blocks to the queue AND iterates over the queue to execute the blocks, then no problem occurs.
Like the reference to an object gets “lost” as the step: method is left?
I don’t understand much in this area and will need more help!
edit:
James, just tried the following to avoid that reference cyle:
NSString *userName = @"James";
[IRQ addObject:^{ NSLog(@"hello %@", userName); } ];
and it also happens. How would your solution apply to this?
Thanks in advance!
When you create a block with the
^{}syntax, it’s created on the stack. To persist the block for a long period of time (beyond the scope of the function that creates it), you must copy the block into the heap:If using ARC, skip the
-autoreleasemessage.