在块中使用局部变量名 "self" 是否正确?
Is it correct to use local variable name "self" in blocks?
我发现构造 __strong typeof(self)self = weakSelf.
它允许删除 NSAssert 宏 self 捕获,但我怀疑这样使用它是否正确?
__weak typeof(self)weakSelf = self;
self.signupBlock = ^{
__strong typeof(self)self = weakSelf;
NSLog (@"%d", self.property)
NSAssert((self.property > 5), @"Some message");
}
请指教。
抱歉,我不得不先说使用
__strong typeof(self)strongSelf = weakSelf;
构造结果警告和我想内存循环,当NSAssert宏使用时,因为它包含self in.
self
只是一个变量名,所以在本地重新定义它是完全可以的。它甚至可能比
更受欢迎
__strong typeof(weakSelf) strongSelf = weakSelf;
因为
- 它使代码易于阅读
- 它可以防止您错误地引用 "real"
self
并可能创建保留循环。
此外,您可能想查看 this question for discussion when to use weak / strong self
in blocks, and libextobjc 库的答案以获得简洁的 @weakify
/ @strongify
宏。
将代码更改为,以便清楚地表明您仅指块中的 strongSelf
:
__weak typeof(self) weakSelf = self;
self.signupBlock = ^{
typeof(weakSelf) strongSelf = weakSelf;
if strongSelf {
NSLog (@"%d", strongSelf.property)
NSAssert((strongSelf.property > 5), @"Some message");
}
}
您的代码设置了与自身的弱连接 __weak typeof(self) weakSelf = self;
。然后当它稍后需要调用 self 时,它会建立一个与 self typeof(weakSelf) strongSelf = weakSelf;
的强连接并检查 self 是否还在(尚未释放)if strongSelf {
。如果是这样,强连接将使它保持活动状态,而其余代码是 运行,这在许多情况下可能涉及另一个块来调用主线程(即强连接)。
是的,在 ObjC 中使用 self
作为变量名是可以的。
我为需要打破由存储块引起的保留循环的情况制作了一个奇特的宏:
#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)
你可以这样使用:
WeakenSelf {
_signupBlock = ^{
RecoverSelf {
NSLog (@"%d", self.property)
NSAssert((self.property > 5), @"Some message");
}
}
}
NSAssert
只应在 Objective-C 方法中使用,因此它使用 self
和 _cmd
。块不是 Objective-C 方法,因此您不应在其中使用 NSAssert
。您可能应该改用 NSCAssert
。
我发现构造 __strong typeof(self)self = weakSelf.
它允许删除 NSAssert 宏 self 捕获,但我怀疑这样使用它是否正确?
__weak typeof(self)weakSelf = self;
self.signupBlock = ^{
__strong typeof(self)self = weakSelf;
NSLog (@"%d", self.property)
NSAssert((self.property > 5), @"Some message");
}
请指教。
抱歉,我不得不先说使用 __strong typeof(self)strongSelf = weakSelf;
构造结果警告和我想内存循环,当NSAssert宏使用时,因为它包含self in.
self
只是一个变量名,所以在本地重新定义它是完全可以的。它甚至可能比
__strong typeof(weakSelf) strongSelf = weakSelf;
因为
- 它使代码易于阅读
- 它可以防止您错误地引用 "real"
self
并可能创建保留循环。
此外,您可能想查看 this question for discussion when to use weak / strong self
in blocks, and libextobjc 库的答案以获得简洁的 @weakify
/ @strongify
宏。
将代码更改为,以便清楚地表明您仅指块中的 strongSelf
:
__weak typeof(self) weakSelf = self;
self.signupBlock = ^{
typeof(weakSelf) strongSelf = weakSelf;
if strongSelf {
NSLog (@"%d", strongSelf.property)
NSAssert((strongSelf.property > 5), @"Some message");
}
}
您的代码设置了与自身的弱连接 __weak typeof(self) weakSelf = self;
。然后当它稍后需要调用 self 时,它会建立一个与 self typeof(weakSelf) strongSelf = weakSelf;
的强连接并检查 self 是否还在(尚未释放)if strongSelf {
。如果是这样,强连接将使它保持活动状态,而其余代码是 运行,这在许多情况下可能涉及另一个块来调用主线程(即强连接)。
是的,在 ObjC 中使用 self
作为变量名是可以的。
我为需要打破由存储块引起的保留循环的情况制作了一个奇特的宏:
#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)
你可以这样使用:
WeakenSelf {
_signupBlock = ^{
RecoverSelf {
NSLog (@"%d", self.property)
NSAssert((self.property > 5), @"Some message");
}
}
}
NSAssert
只应在 Objective-C 方法中使用,因此它使用 self
和 _cmd
。块不是 Objective-C 方法,因此您不应在其中使用 NSAssert
。您可能应该改用 NSCAssert
。