Objective C - 如何等待异步调用完成
Objective C - How to wait for the asynchronous call to finish
我是 iOS 的开发新手。我已经搜索并尝试了几种方法,但程序不想等待异步调用完成。
调试时,函数CheckForHost先returns-1作为retVal。这会导致调用该函数的方法继续。一秒钟后,程序返回 CheckForHost 函数,将正确的值设置为 retVal。我也试过 NSCondition 但也不走运...
有人可以告诉我我做错了什么或者应该做些什么吗?非常感谢您的帮助!
代码如下:
-(int)CheckForHost
{
InternetActive = -1;
HostActive = -1;
dispatch_queue_t myQueue = dispatch_queue_create("my queue", NULL);
__block int retVal = -1;
dispatch_async(myQueue, ^{
[self HostInit];
dispatch_async(dispatch_get_main_queue(), ^{
[internetReachable stopNotifier];
[hostReachable stopNotifier];
[[NSNotificationCenter defaultCenter] removeObserver:self];
if (InternetActive == 0) {
retVal = 0;
} else if (HostActive == 0) {
retVal = 1;
} else
retVal = 2;
});
});
return retVal;
}
-(void)HostInit
{
// check for internet connection
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkNetworkStatus:) name:kReachabilityChangedNotification object:nil];
internetReachable = [Reachability reachabilityForInternetConnection];
[internetReachable startNotifier];
// check if a pathway to a random host exists
hostReachable = [Reachability reachabilityWithHostName:@"www.apple.com"];
[hostReachable startNotifier];
// now patiently wait for the notification
}
-(void)checkNetworkStatus:(NSNotification *)notice
{
// called after network status changes
NetworkStatus internetStatus = [internetReachable currentReachabilityStatus];
switch (internetStatus)
{
case NotReachable:
{
NSLog(@"The internet is down.");
InternetActive = 0;
break;
}
case ReachableViaWiFi:
{
NSLog(@"The internet is working via WIFI.");
InternetActive = 1;
break;
}
case ReachableViaWWAN:
{
NSLog(@"The internet is working via WWAN.");
InternetActive = 1;
break;
}
}
NetworkStatus hostStatus = [hostReachable currentReachabilityStatus];
switch (hostStatus)
{
case NotReachable:
{
NSLog(@"A gateway to the host server is down.");
HostActive = 0;
break;
}
case ReachableViaWiFi:
{
NSLog(@"A gateway to the host server is working via WIFI.");
HostActive = 1;
break;
}
case ReachableViaWWAN:
{
NSLog(@"A gateway to the host server is working via WWAN.");
HostActive = 1;
break;
}
}
}
嗯,如果要等待执行完成,就不要异步执行了。不等待就是异步的意思
因此,如果您想等待,请同步执行块或使用 semaphore。 (我没有说同步执行是个好主意,我只是说,该怎么做。)
我会使用积木,它们既简单又可靠
这是一个带有块的函数示例:
- (void)checkForHostWithBlock:(void (^)(int myReturnedInt))completion{
//Our function does stuff here, i'll copy paste some of your code
InternetActive = -1;
HostActive = -1;
dispatch_queue_t myQueue = dispatch_queue_create("my queue", NULL);
__block int retVal = -1;
dispatch_async(myQueue, ^{
[self HostInit];
dispatch_async(dispatch_get_main_queue(), ^{
[internetReachable stopNotifier];
[hostReachable stopNotifier];
[[NSNotificationCenter defaultCenter] removeObserver:self];
if (InternetActive == 0) {
retVal = 0;
} else if (HostActive == 0) {
retVal = 1;
} else
retVal = 2;
if (completion){
completion(retVal);
}
});
});
}
给你。
您可以像调用任何其他方法一样调用该方法,并且可以使用自动完成功能来确保正确地写下所有内容。
[self checkForHostWithBlock:^(int myReturnInt){
//Executed code when the block is called in checkForHost:
NSLog(@"Here is my int : %i !!", myReturnInt);
}];
请注意,块参数可以为 nil,但您需要确保在您的方法中检查它。
我是 iOS 的开发新手。我已经搜索并尝试了几种方法,但程序不想等待异步调用完成。
调试时,函数CheckForHost先returns-1作为retVal。这会导致调用该函数的方法继续。一秒钟后,程序返回 CheckForHost 函数,将正确的值设置为 retVal。我也试过 NSCondition 但也不走运...
有人可以告诉我我做错了什么或者应该做些什么吗?非常感谢您的帮助!
代码如下:
-(int)CheckForHost
{
InternetActive = -1;
HostActive = -1;
dispatch_queue_t myQueue = dispatch_queue_create("my queue", NULL);
__block int retVal = -1;
dispatch_async(myQueue, ^{
[self HostInit];
dispatch_async(dispatch_get_main_queue(), ^{
[internetReachable stopNotifier];
[hostReachable stopNotifier];
[[NSNotificationCenter defaultCenter] removeObserver:self];
if (InternetActive == 0) {
retVal = 0;
} else if (HostActive == 0) {
retVal = 1;
} else
retVal = 2;
});
});
return retVal;
}
-(void)HostInit
{
// check for internet connection
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkNetworkStatus:) name:kReachabilityChangedNotification object:nil];
internetReachable = [Reachability reachabilityForInternetConnection];
[internetReachable startNotifier];
// check if a pathway to a random host exists
hostReachable = [Reachability reachabilityWithHostName:@"www.apple.com"];
[hostReachable startNotifier];
// now patiently wait for the notification
}
-(void)checkNetworkStatus:(NSNotification *)notice
{
// called after network status changes
NetworkStatus internetStatus = [internetReachable currentReachabilityStatus];
switch (internetStatus)
{
case NotReachable:
{
NSLog(@"The internet is down.");
InternetActive = 0;
break;
}
case ReachableViaWiFi:
{
NSLog(@"The internet is working via WIFI.");
InternetActive = 1;
break;
}
case ReachableViaWWAN:
{
NSLog(@"The internet is working via WWAN.");
InternetActive = 1;
break;
}
}
NetworkStatus hostStatus = [hostReachable currentReachabilityStatus];
switch (hostStatus)
{
case NotReachable:
{
NSLog(@"A gateway to the host server is down.");
HostActive = 0;
break;
}
case ReachableViaWiFi:
{
NSLog(@"A gateway to the host server is working via WIFI.");
HostActive = 1;
break;
}
case ReachableViaWWAN:
{
NSLog(@"A gateway to the host server is working via WWAN.");
HostActive = 1;
break;
}
}
}
嗯,如果要等待执行完成,就不要异步执行了。不等待就是异步的意思
因此,如果您想等待,请同步执行块或使用 semaphore。 (我没有说同步执行是个好主意,我只是说,该怎么做。)
我会使用积木,它们既简单又可靠
这是一个带有块的函数示例:
- (void)checkForHostWithBlock:(void (^)(int myReturnedInt))completion{
//Our function does stuff here, i'll copy paste some of your code
InternetActive = -1;
HostActive = -1;
dispatch_queue_t myQueue = dispatch_queue_create("my queue", NULL);
__block int retVal = -1;
dispatch_async(myQueue, ^{
[self HostInit];
dispatch_async(dispatch_get_main_queue(), ^{
[internetReachable stopNotifier];
[hostReachable stopNotifier];
[[NSNotificationCenter defaultCenter] removeObserver:self];
if (InternetActive == 0) {
retVal = 0;
} else if (HostActive == 0) {
retVal = 1;
} else
retVal = 2;
if (completion){
completion(retVal);
}
});
});
}
给你。
您可以像调用任何其他方法一样调用该方法,并且可以使用自动完成功能来确保正确地写下所有内容。
[self checkForHostWithBlock:^(int myReturnInt){
//Executed code when the block is called in checkForHost:
NSLog(@"Here is my int : %i !!", myReturnInt);
}];
请注意,块参数可以为 nil,但您需要确保在您的方法中检查它。