0

With the recent XCode update some code blocks are displaying as warnings where "Block implicitly retains 'self'"

It is my understanding that the when you create blocks it is best practice to create a weak self to keep from creating a strong reference that will not be garbage collected.

In the below example I set the myArray to self->myArray as recommended by XCode. Does this create the strong reference? Why can't I use 'weakSelf->myArray`? Attempting to do so results in this error:

Dereferencing a __weak pointer is not allowed due to possible null value caused by race condition, assign it to strong variable first

I thought the whole point was to create weak refrences? Isn't weakSelf just a pointer to self?

Is the self-> even necessary in the below instance?

@interface SomeViewController (){
    NSMutableArray * myArray;
}
@end


- (void) doSomethingInBackground {
    // Do NSURLSessionTask on the background and onCompletion call mySuccessBlock.
}



- (SomeBlock) mySuccessBlock {

    __block __typeof__(SomeViewController) __weak * weakSelf = self;

    return ^(NSDictionary* result){

//this line is my related to my question
        self->myArray = [weakSelf sortResultsAlphabetically: result];

        dispatch_async(dispatch_get_main_queue(), ^{
            [weakSelf.tableView reloadData]
        });

    };
}

Would recasting to be the correct way?

SomeViewController * strongSelf = weakSelf;
strongSelf->myArray = [weakSelf sortResultsAlphabetically: result];
user-44651
  • 3,924
  • 6
  • 41
  • 87

1 Answers1

2

The error message is right. You have to do the "weak-strong dance". You are only doing half of the dance. Pass self into the block as weak, but then immediately assign it, inside the block, to a strong reference (as in your edited "Would recasting to be the correct way?").

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • So inside the block I should recast to `strongSelf `and then access the array through the `strongSelf` reference? – user-44651 Apr 20 '18 at 14:39
  • Yes. For the full form of the "weak-strong dance", see my answer here: https://stackoverflow.com/a/8248598/341994 – matt Apr 20 '18 at 14:40
  • Does the recast mater if it is in the main thread or the background thread? – user-44651 Apr 20 '18 at 14:40
  • No, I don't think so. I've never jumped onto the main thread just to do the assignment to a strong ref. – matt Apr 20 '18 at 14:41
  • 1
    Perhaps you could avoid the warning by not dereferencing; use a property instead of `->`. But don't use that as an excuse not to do the full weak-strong dance. Do the dance correctly and fully. – matt Apr 20 '18 at 14:42
  • One last question, looking at my "Would recasting to be the correct way?" example. Should the `sortResultsAlphabetically` use the weak or strong reference? – user-44651 Apr 20 '18 at 14:43
  • Here's the spot in my book where I give a full explanation of the weak-strong dance. http://www.apeth.com/iOSBook/ch12.html#EXstrongWeakDance – matt Apr 20 '18 at 14:45
  • Everything inside the block should use the strong reference. The weak reference is just to pass the reference into the block. You then _immediately_ switch to strong. That is the dance. Do it. – matt Apr 20 '18 at 14:46
  • Perfect! Thank you – user-44651 Apr 20 '18 at 14:46