1
votes

OK, this code on ARC holds self inside the block:

dispatch_async(someQ, ^{
    [self doSomething];
});

and that can be solved by

__weak MyRequest *weakSelf = self;
dispatch_async(someQ, ^{
    [weakSelf doSomething];
});

but what if doSomething has a lot of references to self? Because doSomething code will run inside the block isn't the same of all code of doSomething is on the block directly?

Do I need to pass weakSelf to doSomething so the method can use weakself references instead of self? Something like

__weak MyRequest *weakSelf = self;
dispatch_async(someQ, ^{
    [weakSelf doSomethingUsingThisSelf:weakself];
});
1
doSomething is already called on the weak reference.rmaddy
yes, I know but inside doSomething there are a bunch of references to self...Duck
So what's the question? What do you need to know about self inside the doSomething method?rmaddy
if those selfs will hold references to self, not deallocating.Duck
It all depends on the code in doSomething which you haven't provided.rmaddy

1 Answers

1
votes

By doing:

MyRequest *__weak weakSelf = self;
dispatch_async(someQ, ^{
    [weakSelf doSomething];
});

...when there are no more references to self, weakSelf automatically becomes nil. So the async callback will end up sending doSomething to nil in the even the object is destroyed before the callback, which will do nothing.

If weakSelf is not nil, it's just a pointer to an object. When you send a selector to an object, there two implicit arguments: self and _cmd (see the documentation for IMP), section 6.1). So weakSelf becomes the implicit self in those calls. At that point, self is a strong reference, so the object won't get destroyed out from underneath you during the doSomething call chain, but referencing self from doSomething doesn't cause a reference count to increment because the block doesn't know anything about what goes on inside of doSomething.