objective-cnsdictionaryobjective-c-blocksdispatch

Objective-C: How to build command dispatch table?


I am building a command dispatch table in Objective-C using ARC.

Does this form look good or is there a better alternative:

self.commandTable = [
    @{
        @"command1" : ^(id value) { return [self runCommand1:value]; },
        @"command2" : ^(id value) { return [self runCommand2:value]; },
     } mutableCopy  ];

Solution

  • I see at least two problems with your code.

    First, stack based blocks (like the two you define in your code) won't be retained automatically when you pass them to the collection. So most likely when you will want to execute the block, your app will crash. This is very nicely explained in the answer of the question pointed out by @Josh in the comments: Block gets released whilst in NSDictionary (ARC). You should use the copy method on the block to create a heap based copy that can be retained by ARC.

    Second, after you inserted the copy methods, you will have a retain cycle. Your object "self" retains the commandTable dictionary, the dictionary will retain your blocks (that's your intention, you don't want your blocks go away), and as you use the same object "self" in the blocks, your blocks will retain your "self" object. To avoid this define a __weak local variable to your "self" object as also described in the Working with blocks chapter of the documentation:

    MyClass* __weak weakSelf = self;
    self.commandTable = [@{
                         @"command1" : ^(id value) { return [weakSelf runCommand1:value]; },
                         @"command2" : ^(id value) { return [weakSelf runCommand2:value]; },
                      } mutableCopy];
    

    Otherwise your pattern might do the work well.