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 }.