我有一个名为MadsAdViewController
的对象,它以异步方式请求广告,并在方法didReceiveResponse
上回调。在具有大量内存使用量的应用程序中,dealloc方法被称为非常快,有时甚至在didReceiveResponse
方法仍在运行时。这会导致崩溃,因为我称之为竞争条件。如输出所示,在主线程上调用didReceiveResponse
和dealloc
。
为什么dealloc
不等待方法完成?为什么@synchronized
块不起作用?我该如何解决这个问题?
-(void)didReceiveResponse:(MadsAdResponse*) inAdResponse {
NSLog(@"didReceiveResponse: main thread? = %i, address = %p", [NSThread isMainThread], self);
@synchronized (self) {
//... (lots of stuff that takes a while)
[self logEvent:logAction eventName:EVENT_INIT action:ACTION_VIEW extra:nil];
}
NSLog(@"done with didReceiveResponse response")
}
- (void)dealloc {
@synchronized (self) {
NSLog(@"in sync block in dealloc of object %p", self);
//lots of releases
}
[super dealloc]
}
这是输出:
didReceiveResponse: main thread? = 1, address = 0x139d50b0
in sync block in dealloc of object 0x139d50b0
然后应用程序崩溃:
*** -[[MadsAdViewController logEvent:eventName:action:extra:]: message sent to deallocated instance 0x139d50b0
答案 0 :(得分:0)
好的,转而在块和上面列出的这段代码之间进行了很好的交互。
对于上下文,我们的图书馆被外部方以我们不推荐的方式使用。
这就是它周围发生的事情:
XXXMadsAdViewController *adViewController = [[[XXXMadsAdViewController alloc]init]autorelease];
self.adViewController = adViewController;
[self.adViewController loadAdWithCompletionHandler:^(BOOL success) {
//stuff
}];
XXXMadsAdViewController扩展了MadsAdViewController ,因为它是委托以接收方法调用didReceivePartialAd
。我在方法[self.delegate didReceivePartialAd]
中调用了didReceiveResponse
,我在原始问题中未包含该内容,而 [self logEvent];
现在,有时self.adViewController
已经被释放,但是这个块仍在等待回调。在didReceivePartialAd
上回调时,块被处理,self.adViewController
再次释放,应用程序崩溃。
我通过将didReceivePartialAd
作为方法didReceiveResponse
的最后一个语句来解决问题。
谢谢你们,没有你的指示,我仍然认为这是一场竞争条件!