使用目标选择器保留循环
retain cycle with target-selector
我是retain cycle的新手,如果我的情况落入其中我会很困惑。
我有一个单身人士class
Singleton.h
@interface Singleton : NSObject
+ (Singleton *)sharedInstance;
- (void)doSomethingWithData:(NSDictionary *)data untilDoneReturnToTarget:(id)target selector:(SEL)selector;
@end
Singleton.m
@implementation RequestSingleton
static Singleton *shared = nil;
#pragma mark - System
- (id)init {
self = [super init];
if (self) {
}
return self;
}
#pragma mark - Interface
+ (Singleton *)sharedInstance {
static dispatch_once_t pred;
dispatch_once(&pred, ^{
shared = [[Singleton alloc] init];
});
return shared;
}
- (void)doSomethingWithData:(NSDictionary *)data untilDoneReturnToTarget:(id)target selector:(SEL)selector {
[someClass doSomething:data
completionHandler: ^{
if ([target respondsToSelector:selector]) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
[target performSelector:selector
withObject:someObject]; // is this a retain-cycle?
#pragma clang diagnostic pop
}
}];
}
现在在视图控制器中,我调用 Singleton
中定义的 doSomethingWithData:untilDoneReturnToTarget:selector:
class:
- (void)function {
Singleton *singleton = [Singleton sharedInstance]
[singleton doSomethingWithData:someData
target:self
selector:@selector(processResult:)];
}
- (void)processResult:(id)data {
…
}
我不确定我在 doSomethingWithData:untilDoneReturnToTarget:selector:
中的实现是否陷入了保留周期?我应该在块实现中使用 weakTarget
而不是 target
吗?请帮我解释一下。
提前致谢。
据我所知,您的代码中没有保留循环。但是您正在延长目标的生命周期,直到您完成数据处理。
如果您想保持相同的行为但仅在目标仍然存在时才发出回调,请使用弱引用
这是一篇可能对您有所帮助的好文章http://digitalleaves.com/blog/2015/05/demystifying-retain-cycles-in-arc/
Update:retain cycle最常见的一种情况是相互强引用:object → block and block → object。有时你甚至可以通过使用 API 在不知情的情况下引入它,如果你不小心,它会在内部创建一个保留循环,例如ReactiveCocoa(这就是为什么他们甚至有宏来对抗它,称为 weakify
和 strongify
)。
如果你有一个单例,它无论如何都不会被释放,即使没有保留周期。
我是retain cycle的新手,如果我的情况落入其中我会很困惑。
我有一个单身人士class
Singleton.h
@interface Singleton : NSObject
+ (Singleton *)sharedInstance;
- (void)doSomethingWithData:(NSDictionary *)data untilDoneReturnToTarget:(id)target selector:(SEL)selector;
@end
Singleton.m
@implementation RequestSingleton
static Singleton *shared = nil;
#pragma mark - System
- (id)init {
self = [super init];
if (self) {
}
return self;
}
#pragma mark - Interface
+ (Singleton *)sharedInstance {
static dispatch_once_t pred;
dispatch_once(&pred, ^{
shared = [[Singleton alloc] init];
});
return shared;
}
- (void)doSomethingWithData:(NSDictionary *)data untilDoneReturnToTarget:(id)target selector:(SEL)selector {
[someClass doSomething:data
completionHandler: ^{
if ([target respondsToSelector:selector]) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
[target performSelector:selector
withObject:someObject]; // is this a retain-cycle?
#pragma clang diagnostic pop
}
}];
}
现在在视图控制器中,我调用 Singleton
中定义的 doSomethingWithData:untilDoneReturnToTarget:selector:
class:
- (void)function {
Singleton *singleton = [Singleton sharedInstance]
[singleton doSomethingWithData:someData
target:self
selector:@selector(processResult:)];
}
- (void)processResult:(id)data {
…
}
我不确定我在 doSomethingWithData:untilDoneReturnToTarget:selector:
中的实现是否陷入了保留周期?我应该在块实现中使用 weakTarget
而不是 target
吗?请帮我解释一下。
提前致谢。
据我所知,您的代码中没有保留循环。但是您正在延长目标的生命周期,直到您完成数据处理。
如果您想保持相同的行为但仅在目标仍然存在时才发出回调,请使用弱引用
这是一篇可能对您有所帮助的好文章http://digitalleaves.com/blog/2015/05/demystifying-retain-cycles-in-arc/
Update:retain cycle最常见的一种情况是相互强引用:object → block and block → object。有时你甚至可以通过使用 API 在不知情的情况下引入它,如果你不小心,它会在内部创建一个保留循环,例如ReactiveCocoa(这就是为什么他们甚至有宏来对抗它,称为 weakify
和 strongify
)。
如果你有一个单例,它无论如何都不会被释放,即使没有保留周期。