Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Objective-C, what does it mean to assign a weak to a strong within a block?

In Objective-C, what does it mean to assign a weak to a strong within a block? What's happening behind the scene?

e.g.

__weak __typeof(self) wself = self;

void (^cmd)() = ^(){
    __strong __typeof(self) sself = wself;
    if (!sself) return;
    ...
};
like image 646
Boon Avatar asked Dec 16 '13 17:12

Boon


People also ask

What is strong and weak in Objective C?

strong is the default. An object remains “alive” as long as there is a strong pointer to it. weak specifies a reference that does not keep the referenced object alive. A weak reference is set to nil when there are no strong references to the object.

What is weak reference in Objective C?

Pointers that are not retained are often referred to as “weak” in Objective-C documentation that predates the garbage collector. These are references that are allowed to persist beyond the lifetime of the object. Unfortunately, there is no automatic way of telling whether they are still valid.

Why do you generally create a weak reference when using self in a block?

For many of us, it's best practice to always use weak combined with self inside closures to avoid retain cycles. However, this is only needed if self also retains the closure. By adding weak by default you probably end up working with optionals in a lot of cases while it's actually not needed.

What is difference between strong and weak in Swift?

For example, a strong reference keeps a firm hold on instances and doesn't allow deallocation by ARC. Similarly, a weak reference cannot protect the instances from being deallocated by ARC. Before you learn about strong and weak reference, make sure to understand how classes and objects work in Swift.


1 Answers

The intent here is two-fold:

  1. First, is the use of:

    __weak __typeof(self) wself = self;
    

    This ensures that the cmd block does not maintain a strong reference to self. This ensures that, if cmd was an instance variable of the class, that you don't end up with a strong reference cycle. If you don't use this wself pattern, the class that has cmd as an instance variable would never be released and you'd leak the object that has cmd as an instance variable.

    For more information, see the Avoid Strong Reference Cycles when Capturing self section of the Programming with Objective-C: Working With Blocks document.

  2. Second, the use of the following within the block:

    __strong __typeof(self) sself = wself;
    if (!sself) return;
    

    This ensures that, if the block starts execution, if wself was already deallocated, the block would quit. But if wself has not yet been deallocated, by assigning sself, you're making sure that the object will be retained during the execution of the block.

    Also, if you reference any ivars in the block, be aware that you want to dereference them (because otherwise there is an implicit reference to self in the block, potentially leading to that strong reference cycle). But you cannot dereference ivars using a weak pointer (e.g. wself->someIvar is not permitted), but you can with this local strong pointer (e.g. sself->someIvar is ok). Generally you shouldn't be dereferencing ivars anyway, but rather use properties, but nonetheless it's another reason to use a local strong reference to self.

Often, you'll see this construct in conjunction with a class property (or an ivar):

@property (nonatomic, copy) void (^commandBlock)(void);

And, as a matter of convention, you'll generally see more descriptive variable names, weakSelf and strongSelf, thus:

__weak __typeof(self) weakSelf = self;

self.commandBlock = ^(){
    __strong __typeof(self) strongSelf = weakSelf;
    if (!strongSelf) return;
    ...
};

This weakSelf/strongSelf pattern is very common when you have your own block properties to your class and you want to (a) prevent strong reference cycles (aka retain cycles); but (b) want to ensure that the object in question cannot be deallocated in the middle of the execution of the block.

like image 148
Rob Avatar answered Oct 06 '22 01:10

Rob