0

我正在尝试使用大中央调度设置和 NSURL,但是在您尝试在大中央调度块之外访问它之前,该变量似乎已设置并可访问。

-(void)viewDidLoad {

[super viewDidLoad];

dispatch_queue_t backgroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(backgroundQueue,^{

    self.ubiquitousURL = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];

   NSLog(@"ubiq inside: %@", self.ubiquitousURL);

    if (self.ubiquitousURL) {

        self.iCloudDocURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@Documents", self.ubiquitousURL]];
        self.iCloudDocString = [self.iCloudDocURL absoluteString];

        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(loadFiles) name: UIApplicationDidBecomeActiveNotification object:nil];

    } else {

        /* change to the main queue if you want to do something with the UI. For example: */
        dispatch_async(dispatch_get_main_queue(),^{

            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Please enable iCloud" message:nil delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];

            [alert show];

        });

    }

});


NSLog(@"ubiq outside: %@", self.ubiquitousURL);

}

第一个NSLogubiq inside返回正确的 URL 开头,而ubiq outside返回 NULL。我正在使用 ARC,因此无需提及内存或类似内容……这是 GCD 问题。

你知道为什么self.ubiquitousURL在 GCD 块之外无法访问吗?谢谢。

4

2 回答 2

4

您正在进行异步调用。所以NSLog(@"ubiq outside: %@", self.ubiquitousURL);无论你在 backgroundQueue 中的代码是否完成,这条线都会被执行。

您将首先看到外部日志,然后是内部日志。

于 2012-07-08T00:30:21.803 回答
3

dispatch_async意思是“稍后运行”。因此,块内的代码不会立即运行;NSLog它在“外部”调用已经运行之后的某个时间运行。例如,如果您要sleep(5)在调用之前放置NSLog,您可能会看到该值。(不过,您不应该在实际代码中真正这样做;它基本上会使应用程序冻结五秒钟。)

如果您想在设置该属性后在主队列上运行更多代码,请执行以下操作:

dispatch_async(backgroundQueue,^{
    self.ubiquitousURL = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];

    NSLog(@"ubiq inside: %@", self.ubiquitousURL);

    if (self.ubiquitousURL) {
        self.iCloudDocURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@Documents", self.ubiquitousURL]];
        self.iCloudDocString = [self.iCloudDocURL absoluteString];

        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(loadFiles) name: UIApplicationDidBecomeActiveNotification object:nil];

        // ************** NEW HOTNESS HERE **************
        dispatch_async(dispatch_get_main_queue(),^{
            NSLog(@"ubiq outside: %@", self.ubiquitousURL);
        });
    } else {
        /* change to the main queue if you want to do something with the UI. For example: */
        dispatch_async(dispatch_get_main_queue(),^{
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Please enable iCloud" message:nil delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
            [alert show];
        });
    }
});

NSLog如果您在检索 iCloud URL 后想要执行此操作,请将该行替换为执行实际工作的方法调用。

于 2012-07-08T00:38:08.560 回答