I really do not know, whether I understood you correctly. Do you mean with "makes retained" "retains"?
However, the difference between the two pieces of code is the time of execution and how references are handled:
Keep in mind that not object references are retained, but the object they points to.
A. Timer
{
__weak typeof(self) weakSelf=self;
_timer=[NSTimer timerWithTimeInterval:0.5 target:weakSelf …];
}
With this code you create an additional local var called weakSelf
, that does not retain the object it points to. Moreover, the extent ("lifetime") of weakSelf
ends with the C-block (not the closure what you called __block
), that means with the closing }
. So we have:
{
__weak typeof(self) weakSelf=self;
// does not retain self; no problem
_timer=[NSTimer timerWithTimeInterval:0.5 target:weakSelf …];
// weakSelf dies, since it is weak nothing happens.
}
In such a case it is completly meaningless to weakify self
:
{
id anotherSelf=self;
// does retain self: +1;
_timer=[NSTimer timerWithTimeInterval:0.5 target:weakSelf …];
// anotherSelf dies: -1
}
This is always balanced, because ARC care about it. No problem.
So why is there a retain cycle? It is "inside the timer." According to the documentation:
The object to which to send the message specified by aSelector when the timer fires. The timer maintains a strong reference to this object until it (the timer) is invalidated.
Therefore, lets go back to your example:
{
__weak typeof(self) weakSelf=self;
// does not retain self;
_timer=[NSTimer timerWithTimeInterval:0.5 target:weakSelf …];
// timer retains the object, weakSelf points to: +1.
// self retains the timer: +1
// result: retain cycle
// weakSelf dies, since it is weak nothing happens.
}
What -timerWithInterval…
does, does not depend of the strength of weakSelf
. The method does not even see the strength of the reference. It retains an object that the argument points to. Period.
B. Block
Having a block it is different:
{
__weak typeof(self) weakSelf=self;
// does not retain self; no problem
_block=^{
…
};
// weakSelf dies, since it is weak nothing happens.
}
As you can see, there is no problem. Why can be there a retain cycle? This is quite easy: Having a reference inside the block, the referred object is retained when the block is created (similar to timers) and the reference is strong(different to timers):
{
__weak typeof(self) weakSelf=self;
// does not retain self; no problem
_block=^{
… self … // the object self points to is retained, because self is strong. +1
… weakSelf … // the object weakSelf points to is not retained.
…
};
// weakSelf dies, since it is weak nothing happens.
}
This reference lives as long as the block lives. You have to read it correctly: It is like the reference itself has a longer lifetime. Therefore it depends of the strength of the reference.
So there is a big difference, whether you use weakSelf
or self
(or any other weak or strong reference.)
What is done inside the block …:
_block=^{
__strong id strongSelf=weakSelf;
};
… is meaningless, because this is done, when the block is executed and the local strongSelf
will immediately lose its extent. (Again with the closing }
.