gpt4 book ai didi

iphone - PerformSelectorOnMainThread 抛出消息已释放

转载 作者:行者123 更新时间:2023-12-03 21:05:22 24 4
gpt4 key购买 nike

在解析twitter数据时,我使用线程调用主URL来下载数据。它完美地完成了下载,但是当我在下载数据时按下后退按钮时,它会抛出performSelectorOnMainThread 消息已释放。我知道我们可以使用 isCancelled 但它对我来说还不起作用。有没有人遇到过这个问题并解决了。

- (void)LoadTwitterData
{
NSString *urlString =@"http://search.twitter.com/search.json?q=tabc&result_type=recent&rpp=2500";
NSURL *url = [NSURL URLWithString:urlString];

NSString *jsonString = [NSString stringWithContentsOfURL:url];
NSDictionary *values = [jsonString JSONValue];

/**** Throws here *****/
[self performSelectorOnMainThread:@selector(didFinishLoadingResults:) withObject:values waitUntilDone:NO];

}

最佳答案

如果您使用 self 上的选择器分离线程,则需要确保 self 在该线程的持续时间内保留,否则(如您的case) self 可以被释放,并且你的线程将尝试回调到僵尸中。最简单的方法是将 self 作为参数传递给线程。如果您使用 performSelectorInBackground:withObject: 您应该执行以下操作:

[self performSelectorInBackground:@selector(LoadTwitterData) withObject:self];

或者,如果您使用 NSThread,您应该将 self 传递给 object: 初始值设定项参数。

事实上,使用线程方法最安全的方法是将方法设置为静态,如下所示:

+ (void)LoadTwitterData:(id)arg
{
// ...
MyController *self = arg;

// ... do work

[self performSelectorOnMainThread:@selector(didFinishLoadingResults:)
withObject:values waitUntilDone:NO];

}

这样您就无法意外访问实例变量,从而避免了各种多线程问题。线程需要的任何和所有数据,包括要回调的 self ,都应该作为“arg”传入,它可以是数组或字典或您需要的任何数据。这样您就知道线程所需的所有内容都将在线程持续时间内保留,并且因为您没有通过 self 访问实例变量,所以另一个线程无法在您下面更改它们.

您应该在线程方法中做的另一件事是用自动释放池包装整个事情:

- (void)LoadTwitterData
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
@try {
// ...
} @finally {
[pool drain];
}
}

关于iphone - PerformSelectorOnMainThread 抛出消息已释放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7741479/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com