Mik*_*ike 42 objective-c ios libextobjc
我开始libextobjc(集成https://github.com/jspahrsummers/libextobjc)到我的iOS应用程序主要是为了充分利用EXTScope的中@strongify和@weakify,但也继续深入过程之前,有几个问题.
这是一个有意过度复杂的例子,试图解决如何处理这个问题:
- (void)someMethod {
if (self.someBOOL) {
_someObjectInstanceVar = [Object objectWithCompletionHandler:^{
// self reference #1
if (self.someProperty) {
// self reference #2
[[Async HTTPRequest] sendAWithID:self.property.id completionHandler:^(void (^)(NewObject *newObject) {
// self reference #3
[self showViewWithObject:newObject handler:^{
// self reference #4
[self reloadData];
}];
}];
}
}];
else {
[[Async HTTPRequest] sendBWithID:self.property.id completionHandler:^{
// self reference #5
[self reloadData];
}];
}
}
Run Code Online (Sandbox Code Playgroud)
我的理解是,如果我想做异步HTTP请求之类的事情,并且在完成处理程序引用self内部,比如[self reloadData],我不需要对强/弱做任何事情,因为请求块本身没有保留完成块,那里保留周期没有问题.在上面的代码示例中,我认为#5是保留周期不是问题的情况.
主要关注的是所有将块作为属性/ init参数的对象,这些对象内部保留在块属性上.在objectWithCompletionHandler方法内部,someObject作为实例变量保存在completionHandler块中,有多个对self的引用,我知道这会引起泄漏.我的主要问题是在这种情况下,您需要如何处理weakify并strongify使其"更安全"?一个@weakify和@strongify调用是否足够,如下所示:
- (void)someMethod {
@weakify (self);
_someObjectInstanceVar = [Object objectWithCompletionHandler:^{
@strongify(self);
...
}
Run Code Online (Sandbox Code Playgroud)
上面的@strongify(self)引用是否足以用于自引用#1,2,3和4,或者我必须(甚至可以工作)获得一个新的弱/强引用以在sendAWithID方法和嵌套中使用reloadData?
编辑:修复代码有问题更有意义,并修复一些语法错误.
Aar*_*ger 80
@strongify工作在@strongify调用之后,块内部self将具有与块外部不同的指针地址.那是因为每次都声明一个新的局部变量.(这就是为什么它会抑制警告,它会"在局部变量影响另一个局部变量时发出警告.")值得阅读并理解这些函数的实现.因此,即使名称相同,也将它们视为单独的引用.@strongifyself-Wshadowstrong
@strongify在你的代码预先假定(这不是真的)每次使用一个块都会创建一个参考周期,你可以:
- (void)someMethod {
if (self.someBOOL) {
@weakify(self);
_someObjectInstanceVar = [Object objectWithCompletionHandler:^{
@strongify(self);
// self reference #1
if (self.someProperty) {
@weakify(self);
// self reference #2
[[Async HTTPRequest] sendAWithID:self.property.id completionHandler:^(void (^)(NewObject *newObject) {
@strongify(self);
// self reference #3
@weakify(self);
[self showViewWithObject:newObject handler:^{
// self reference #4
@strongify(self);
[self reloadData];
}];
}];
}
}];
// etc…
}
Run Code Online (Sandbox Code Playgroud)
但是,请记住,在您第一次使用之后@strongify,self将引用本地堆栈变量.当它们定义的范围结束时(只要您不将它们存储到属性或在嵌套块中使用它们),它们通常会被销毁.所以根据你展示的代码,你只需要它// self reference #1.
阅读单元测试封面@weakify,@strongify将有助于阐明这些功能的正确用法.
要回答关于块的每个嵌套级别中的多个弱化/强化实例是否有效的问题,请回答是.但是没有必要这样做,因为你的第一个@strongify定义已经为你的块的所有内部范围(以及嵌套在它中的块)定义了self.
但是,假设您的块具有不同的生命周期,您可能希望为每个嵌套块添加@strongify,以确保它们都将自己的保留周期保留到其内部范围.
这是解释这种情况的github问题线程:https: //github.com/jspahrsummers/libextobjc/issues/45
| 归档时间: |
|
| 查看次数: |
21375 次 |
| 最近记录: |