无夜之星辰
无夜之星辰

Reputation: 6158

When should we change weakSelf to strongSelf?

I know that when we use block we should use weakSelf to avoid retain cycle.But I saw there is a strongSelf in block sometimes.

What confused me are:

  1. why must change weakSelf to strongSelf?
  2. if we don't change weakSelf to strongSelf what terrible thing would happen?
  3. when should we change weakSelf to strongSelf?

Hope someone can give an exact example.

Thanks in advance.

Upvotes: 11

Views: 7318

Answers (3)

Alex
Alex

Reputation: 159

In any case you need the "self" after the callback return - it is never wrong to turn weak self to strong self, in worst case - just extra code. but the opposite is not true. here is a very simple example where you indeed need a strong ref.

 __weak typeof(self) weakSelf = self;
    [self.bgQueue1 addOperationWithBlock:^{
        [weakSelf doSomeMagic:weakSelf.importentArr arg:number];
        if (weakSelf.importentArr.count == 10){
            //we will have crash(or other unpredictable results) if weakSelf will turns to nil
            [DataBaseClass save:weakSelf.importentArr];
        }
    }];

Upvotes: 0

CRD
CRD

Reputation: 53010

The only reason to capture self, as a weak or strong reference, in a block is because the block uses it in some way.

When self has been captured weakly how it is used will determine when, and if, you need to make a strong copy first.

If the block is going to use the captured reference multiple times then a strong copy should always be made, this insures the reference stays alive across all the uses within the block and avoids the cost of loading a weak reference multiple times.

For example, if the block's function is dependent on whether self still exists then it would be usual to start by making a strong reference and testing it. Something along the lines of:

__weak __typeof(self)weakSelf = self;
myBlock = ^{
    // make local strong reference to self
    __typeof(weakSelf) strongSelf = weakSelf; 
    // check if self still exists and process accordingly
    if (strongSelf)
    {
        // do whatever is needed if "self" still exists
        // strongSelf will keep the object alive for the
        // duration of the call
    }
    else
    {
        // do whatever, if anything, is needed if "self" no longer exists
    }
});

However if the block's operation only optionally requires the use of the object referenced by self then a strong copy may never be made.

HTH

Upvotes: 8

Pochi
Pochi

Reputation: 13459

  1. why must change weakSelf to strongSelf?

Sometimes you want your block to NOT execute if the reference to self is already nil (user dismissed the view). This is why you first use weak references. (COMMON CASE)

However, sometimes you want your block to finish executing ensuring all the things its referencing are alive, but only if "self" is still alive once the block has started. In this case you make the block convert the weak reference into strong. (RARE CASE)

  1. if we don't change weakSelf to strongSelf what terrible thing would happen?

If the block started executing while self is alive (allowing it to begin) but gets deallocated in the middle of the processing (think of a time consuming function such as image processing), and then the block accesses a resource from self (which no longer exists) it will crash.

  1. when should we change weakSelf to strongSelf?

Almost never. The only example I can think of is when your block absolutely needs the resources from "self" once it has begun executing.

There's a more detailed explanation in this answer:

Strong reference in the block, it will be retained?

Upvotes: 19

Related Questions