Reputation: 2107
I`ve found that construction __strong typeof(self)self = weakSelf.
It allows remove NSAssert macro self catching, but I am in doubt is it right to use it in that way?
__weak typeof(self)weakSelf = self;
self.signupBlock = ^{
__strong typeof(self)self = weakSelf;
NSLog (@"%d", self.property)
NSAssert((self.property > 5), @"Some message");
}
Pls advice.
Sorry, I had to say first that using of __strong typeof(self)strongSelf = weakSelf;
construction results to warnings and I suppose to mem cycle, when NSAssert macro used, because it contains self in.
Upvotes: 2
Views: 314
Reputation: 122429
NSAssert
is only supposed to be used in Objective-C methods, and as such it uses self
and _cmd
. A block is not an Objective-C method, and so you should not use NSAssert
in it. You should probably use NSCAssert
instead.
Upvotes: 2
Reputation: 4676
Yeah using self
as variable name in ObjC is fine.
I made a fancy macro for such cases where you need to break a retain cycle caused by a stored block:
#define StrongSelf __strong __typeof__((__typeof__(self))self)
#define WeakSelf __weak __typeof__((__typeof__(self))self)
#define RecoverSelf for (BOOL _continue_loop = YES; _continue_loop; _continue_loop = NO) \
for (StrongSelf this = self; this != nil && _continue_loop; _continue_loop = NO) \
for (StrongSelf self = this; _continue_loop; _continue_loop = NO)
#define WeakenSelf for (BOOL _continue_loop = YES; _continue_loop; _continue_loop = NO) \
for (WeakSelf this = self; _continue_loop; _continue_loop = NO) \
for (WeakSelf self = this; _continue_loop; _continue_loop = NO)
which you can use like that:
WeakenSelf {
_signupBlock = ^{
RecoverSelf {
NSLog (@"%d", self.property)
NSAssert((self.property > 5), @"Some message");
}
}
}
Upvotes: 1
Reputation: 18157
Change the code to, so that it´s clear that you are referring only to strongSelf
in the block:
__weak typeof(self) weakSelf = self;
self.signupBlock = ^{
typeof(weakSelf) strongSelf = weakSelf;
if strongSelf {
NSLog (@"%d", strongSelf.property)
NSAssert((strongSelf.property > 5), @"Some message");
}
}
Your code sets up a weak connection to self __weak typeof(self) weakSelf = self;
. Then when it needs to call self later, it sets up a strong connection to self typeof(weakSelf) strongSelf = weakSelf;
and checks if self is still around (has not been released) if strongSelf {
. If so the strong connection will keep it alive while the rest of the code is run, which might in many instances involve another block to call on the main thread (i.e. hence the strong connection).
Upvotes: 2
Reputation: 3873
self
is just an variable name, so it's perfectly fine to redefine it locally. It might be even preferred to
__strong typeof(weakSelf) strongSelf = weakSelf;
because
self
and potentially creating retain cycles.Additionally, you might want to look at answers to this question for discussion when to use weak / strong self
in blocks, and libextobjc library for neat @weakify
/ @strongify
macros.
Upvotes: 6