【问题标题】:performselector won't executeperformselector 不会执行
【发布时间】:2014-05-01 15:54:42
【问题描述】:

我收到了来自foursquare api 的json 响应。一旦我检查我是否有数据,我就会尝试执行“loadNearestCoffeeShops”方法。在调试过程中,我注意到应用程序在到达 [self performSelector:@selector(loadNearestCoffeeShops:) withObject:data afterDelay:0]; 时就停止了。

这是我的代码...有什么建议吗?

-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation   *)newLocation fromLocation:(CLLocation *)oldLocation
{
    NSLog(@"updated to location");
    //Optional: turn off location services once we've gotten a good location
    [manager stopUpdatingLocation];

    NSURLSession *session = [NSURLSession sharedSession];
    NSString *myURL = [NSString stringWithFormat:@"https://api.foursquare.com/v2/venues/search?client_id=%@&client_secret=%@&v=%@&ll=%f,%f&venue=%@", clientID, clientSecret, version, newLocation.coordinate.latitude, newLocation.coordinate.longitude,venue_type];
    //NSLog(jsonURL);
    NSURLSessionDataTask *dataTask = [session dataTaskWithURL:[NSURL URLWithString:myURL] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        NSMutableDictionary *allCoffeeShops= [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
        NSLog(@"%@", allCoffeeShops);
        if (data)
        {
            [self performSelector:@selector(loadNearestCoffeeShops:) withObject:data afterDelay:0];
        }
        else
        {
            NSLog(@"No Damn Data");
        }
    }];
    [dataTask resume];

【问题讨论】:

  • “应用程序只是停止”:请解释。选择器方法执行了吗?
  • 假设该方法存在,在其中放置一个断点以确定它是否正在执行。您不能真正通过 performSelector 来跟踪它,因为它会被放入运行循环以供以后执行。
  • 在我们知道真正调用了“loadNearestCoffeeShops”之前,无法为您提供帮助。请在“loadNearestCoffeeShops”的第一行放置一个断点。并添加'loadNearestCoffeeShops'的代码来发布。
  • 现在我正在使用“performSelectorOnMainThread”选择器正在执行。
  • 听起来像死锁。您可以通过选择“线程”图标(调试导航器)来查看这一点。将有多个线程在等待。

标签: ios json performselector


【解决方案1】:

或者你可以这样做:

if (data)
{
    [self performSelectorInBackground:@selector(loadNearestCoffeeShops:) withObject:data];
}
....

请记住,如果加载最近的咖啡店需要任何与 UI 相关的工作,那么您可以通过以下方式将其发送回主线程:

[self performSelectorOnMainThread:... withObject:... waitUntilDone:...]

【讨论】:

  • 这条线有效 [self performSelectorOnMainThread:... withObject:... waitUntilDone:...]
【解决方案2】:

来自Apple Documentation

特殊注意事项

此方法注册到其当前上下文的 runloop,并依赖于定期运行的 runloop 才能正确执行。您可能调用此方法并最终注册到一个不会定期自动运行的 runloop 的一个常见上下文是当被调度队列调用时。如果你在 dispatch queue 上运行时需要这种类型的功能,你应该使用 dispatch_after 和相关的方法来获得你想要的行为。

我相信 NSURLSessions 在调度队列中运行,所以使用这种方法会有问题。更好的选择是dispatch_asyncperformSelectorOnMainThread:...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-10
    • 2017-11-21
    相关资源
    最近更新 更多