I’m totally stumped with this one and hope someone could help me out here:
Class A:
- (void)setBlock:(BOOL(^)(id sender))block {
myBlock = Block_copy(block);
}
- (BOOL)runBlock:(id)sender {
myBlock(sender);
}
Class B:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotificationx {
//The outer block provides behaviour according to strategy pattern:
[classAInstance setBlock:^BOOL(id sender) {
NSOperationQueue *queue = [[[NSOperationQueue alloc] init] autorelease];
//The inner block is a special case of behaviour where I want the task to run asynchronously:
[queue addOperationWithBlock:^(void) {
NSLog(@"sender: %@", [sender class]);
[sender doSomething];
}];
return YES;
}];
}
Then later when a GUI event causes classAInstance to call - (BOOL)runBlock;
(which it is supposed to be) I get the following crash stack:
0 objc_exception_throw
3 __forwarding_prep_0___
4 __58-[ClassB applicationDidFinishLaunching:]_block_invoke_037
5 -[NSBlockOperation main]
11 start_wqthread
And the very last debug log that I get is this:
sender: __NSMallocBlock__
-[__NSMallocBlock__ doSomething]: unrecognized selector sent to instance 0x10043f2a0
Now why did the block’s argument suddenly turn into __NSMallocBlock__ in first place?
I was clearly passing something else (namely sender) to it, wasn’t I?
Found the reason. Duh, I feel stupid now.
The mistake was attaching the block (as well as a second one) to my object as associated objects via:
while I should clearly have used this:
FirstBlockKeyandSecondBlockKeythemselves are both0x0obviously, while their own pointers are not.This way it simply called the wrong block (as they both were assigned to the same `0x0′ key). The blocks had different return and argument types, which seem to have caused the strange exchange of passed block arguments. Working fine now.
That being said: Joe, Ryan & wbyoung, thanks for your efforts guys!