I want to reuse an object reference across multiple calls of a single block, and I'm curious: What is the practical difference between the following two approaches?
Using a __block variable:
__block Widget *widget = [self buildNewWidget];
for(Gadget *gadget in self.gadgets) {
    [self useGadget:gadget withCallback:^{
        if([widget isBroken]) {
            widget = [self buildNewWidget];
        }
        gadget.widget = widget;
    }];
}
Using a static variable:
for(Gadget *gadget in self.gadgets) {
    [self useGadget:gadget withCallback:^{
        static Widget *widget;
        if(!widget || [widget isBroken]) {
            widget = [self buildNewWidget];
        }
        gadget.widget = widget;
    }];
}
Obviously these two chunks of code differ from a semantic perspective, but (practically speaking) I believe they do the same basic work. My guess is that there is a difference from a memory management perspective, a performance perspective, or something else. Any insights that illustrate these differences (or explain why they are not different) would be helpful.
An example is worth a thousand words:
(And yes, this is a very simplistic example, but it is mostly equivalent to what you were doing...)
for (int i = 0; i < 3; i++)
{
    // Your example encompasses this scope,
    // not taking into account that we may execute this code multiple times:
    // Call the block
    (^{
        // Every instance/execution of this block will have the same object.
        static Obj *o;
        // Initialize static object
        static dispatch_once_t once;
        dispatch_once(&once, ^{
            o = [Obj new];
        });
        NSLog(@"Object is: %@", o);
    })();
}
// Output:
//   Object is: <Obj: 0x100109fd0>
//   Object is: <Obj: 0x100109fd0>
//   Object is: <Obj: 0x100109fd0>
for (int i = 0; i < 3; i++)
{
    __block Obj *o = [Obj new];
    // Call the block
    (^{
        // This block uses the object from its enclosing scope, which may be different.
        NSLog(@"Object is: %@", o);
    })();
}
// Output:
//   Object is: <Obj: 0x105100420>
//   Object is: <Obj: 0x1003004f0>
//   Object is: <Obj: 0x105300000>
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With