考虑我在我的视图控制器中,我添加了Singleton属性的RACObserve,而在subscribNext里面我有一个自引用。 代码如下:
[RACObserve([Singleton shared], singletonFlag) subscribeNext:^(NSNumber *singletonFlag) {
self.flag = [singletonFlag boolValue];
}];
根据我的理解,我自己并没有强烈提及这个障碍(虽然阻挡了强烈的自我参照),这不应该导致保留周期。 我已经阅读了反应性可可的内存管理https://github.com/ReactiveCocoa/ReactiveCocoa/blob/master/Documentation/Legacy/MemoryManagement.md 其中他们提供了一个例子
[RACObserve(self, username) subscribeNext:^(NSString *username) {
[self validateUsername];
}];
我完全理解为什么它导致了上述情况下的保留周期,我们需要在块内部使用弱自我。 我很困惑为什么在第一种情况下,它会导致保留周期。要确认这一点,只需在viewDidLoad之后粘贴该代码段,然后查看视图控制器是否应该被解除分配。 如果你需要看到更多的单例实现,那就是代码,
@interface Singleton : NSObject
@property (readwrite,nonatomic) BOOL singletonFlag;
@end
@implementation Singleton
+ (Singleton *)shared {
static dispatch_once_t pred = 0;
__strong static id _sharedObject = nil;
dispatch_once(&pred, ^{
_sharedObject = [[self alloc] init];
});
return _sharedObject;
}
- (id)init {
if (self = [super init]) {
NSLog(@"init of %@",NSStringFromClass(self.class));
}
return self;
}
@end
有人对此有所启发吗?
答案 0 :(得分:4)
内部实现非常复杂,是否存在真正的保留周期并不重要。
在这两个例子中,内存泄漏的原因是相同的:
self
由块self
(RACObserve micro隐式使用self
)被解除分配时,RACObserve信号终止。 但是现在单例实例不会dealloc,self
也不会dealloc,因为它已经保留了。所以信号永远不会终止,然后是内存泄漏。
答案 1 :(得分:0)
无论如何,你不应该写
之类的东西[RACObserve([Singleton shared], singletonFlag) subscribeNext:^(NSNumber *singletonFlag) {
self.flag = [singletonFlag boolValue];
}];
相反,写一下
RAC(self, flag) = RACObserve([Singleton shared], singletonFlag);
答案 2 :(得分:0)
问题在于RACObserve()将返回一个RACDisposable对象,您必须处置自己。如果以RAC()= RACObserve()的方式使用它,那么RAC()部分将负责杀死由RACObserve()方法返回的RACDisposable对象。
使用RACObserver时可以进行的一个快速修复:
[RACObserve(self, username) subscribeNext:^(NSString *username) {
[self validateUsername];
}];
是将其转换为: (RACDisposable * disposableSignal;例如以.h声明)
disposableSignal=[RACObserve(self, username) subscribeNext:^(NSString *username) {
[self validateUsername];
}];
并使用[disposableSignal dispose]解除信号分配。例如在viewWillDisappear方法中。基本上,您必须使用dispose方法将其杀死以摆脱它。