我的iOS应用程序中存在这种情况。
我正在向web api发出请求,我正在后台线程中这样做。我有一个名为Service的类,它有这个方法:
- (void)searchForRoutesFrom:(NSNumber *)startStationId
to:(NSNumber *)endStationId
delegate:(id<WAMSServiceDelegate>)delegateOrNil
{
RouteSearchRequest *request = [[RouteSearchRequest alloc] init];
...request populate ...
[NSThread detachNewThreadSelector:@selector(searchForRoutesInTheBackground:)
toTarget:self withObject:request];
}
- (void)searchForRoutesInTheBackground:(RouteSearchRequest *)request
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
...make the request and call back...
}
这很好用,但是如果用户决定离开View(使用此服务),就在线程启动之前,就会释放Service对象。当线程启动时,它将尝试调用searchForRoutesInTheBackground方法,我的应用程序将崩溃。
我可以使用哪些其他方法来运行此线程并处理正在释放的调用对象。
答案 0 :(得分:0)
你可以在启动线程之前retain
调用对象,并在处理结束时(就在返回之前)释放它。
- (void)searchForRoutesFrom:(NSNumber *)startStationId
to:(NSNumber *)endStationId
delegate:(id<WAMSServiceDelegate>)delegateOrNil
{
RouteSearchRequest *request = [[RouteSearchRequest alloc] init];
...request populate ...
[self retain];
[NSThread detachNewThreadSelector:@selector(searchForRoutesInTheBackground:)
toTarget:self withObject:request];
}
- (void)searchForRoutesInTheBackground:(RouteSearchRequest *)request
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
...make the request and call back...
[self release];
}
如果您使用了块,那将自动为您完成,但保留/释放很容易管理这种情况。
答案 1 :(得分:0)
由于您的逻辑信息不足,我不确定是否会根据您的情况正确回答您,但我以不同的方式处理这些情况。我所做的是创建单独的类(MVC模型),用于通过启动请求和处理回调的方法与Web服务进行通信。当回调执行时,有不同的场景 - (使用CoreData持久化结果,我的UI捕获此事件并更新(如果可见),或者将块作为参数传递给发出请求的方法,并在回调中调用并且块被执行,并且通常块以if(!self.view.window) return;
开始,这意味着如果当前视图不可见则不会发生任何事情)。但在这两种情况下,我的请求和回调完全独立于UI,因此不会出现像你这样的问题。
答案 2 :(得分:0)
但是如果用户决定离开View(使用此服务),则只需 在线程启动之前,将释放Service对象。什么时候 线程启动它将尝试并调用 searchForRoutesInTheBackground方法和我的应用程序将崩溃。
这是不可能的。请参阅documentation for +detachNewThreadSelector:toTarget:withObject:。它说
在执行分离线程期间保留对象aTarget和anArgument,然后释放。
这意味着在您致电detachNewThreadSelector:toTarget:withObject:
时会保留该信息。因此,如果该对象在那一刻有效,它将在新线程完成执行之前有效。
如果发生了不好的事情,你必须在其他地方做错的内存管理。例如1)在调用detachNewThreadSelector:toTarget:withObject:
的时间之前,对象已经被释放,或者2)你在不应该的地方过度释放对象。