Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 从多个UIViewController控制对webservice方法的访问_Ios_Objective C_Nslock - Fatal编程技术网

Ios 从多个UIViewController控制对webservice方法的访问

Ios 从多个UIViewController控制对webservice方法的访问,ios,objective-c,nslock,Ios,Objective C,Nslock,我有一个iOS应用程序,带有一个选项卡和3个不同的UIViewController,每个选项卡一个。该应用程序使用SudzC与C#NET webservice接口,从数据库中提取数据 有一个webservice方法是从所有三个视图控制器调用的,但我想强制规定,在任何时间点,只有一个视图控制器可以调用该方法,并且在返回数据之前,没有其他视图控制器可以调用该方法 我试图通过在AppDelegate中定义一个NSLock,然后在每个viewController中实现以下代码来解决这个问题: if([S

我有一个iOS应用程序,带有一个选项卡和3个不同的
UIViewController
,每个选项卡一个。该应用程序使用SudzC与
C#NET webservice
接口,从数据库中提取数据

有一个webservice方法是从所有三个视图控制器调用的,但我想强制规定,在任何时间点,只有一个视图控制器可以调用该方法,并且在返回数据之前,没有其他视图控制器可以调用该方法

我试图通过在
AppDelegate
中定义一个NSLock,然后在每个
viewController
中实现以下代码来解决这个问题:

if([SharedAppDelegate.loginLock lockBeforeDate:[[[NSDate alloc] init] dateByAddingTimeInterval:30.0]])
{
     // got the lock so call the webservice method
     SDZiOSWebService* webService = [SDZiOSWebService service];
     [webService Login:self action:@selector(handleRelogin:) username:userName password:password];
}
else
{
     // can't get lock so logout
     self->reloginInProgress = false;
     [SharedAppDelegate doLogout];
}
webservice返回的处理程序定义为(为清楚起见,已截断)

我的理解是,第一个
UIViewController
会得到一个锁,其他的会阻塞长达30秒,等待获得锁。但是,在少数情况下,如果有多个
viewController
同时尝试访问锁,则会立即出现以下错误:

*** -[NSLock lockBeforeDate:]: deadlock (<NSLock: 0x2085df90> '(null)')
***-[NSLock lockBeforeDate:]:死锁('(null))

谁能告诉我我做错了什么?我对C/C++中的锁有很好的理解,但是这些Objective-C锁已经被难住了。

在我看来,对于这个简单的情况,不应该使用锁(它们是“邪恶的”)

您可以尝试使用NSOperationQueue,设置为一次管理1个并发操作,然后让视图控制器将其web服务调用排入队列:操作队列将保证一次只执行一个操作。 操作队列的另一个优点是,视图控制器可以检查队列是否为空,然后根据当前状态决定是否将其调用排队。 最后,您可以使用KVO观察队列状态,这样每个视图控制器都可以在提交新请求之前简单地进行检查


与使用NSOperationQueue类似的另一种可能性是创建一个专用GCD串行队列,并再次将所有web服务请求排队(包装在块中)。虽然GCD串行队列比NSOperationQueues(IMHO)更易于实现,但它们在可观察性和取消操作的可能性方面并没有提供相同的优势。

如果您只想一次访问一个视图,那么。您可以使用单例类。 这里有一个链接,指向网络上众多示例中的一个。

您还可以使用NSUserDefaults存储bool值,以通知您视图是否正在使用web服务。 一个简单的例子是:

存储价值

[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"active_connection"];
[NSUserDefaults synchronize];
if(![[NSUserDefaults standardUserDefaults] boolForKey:@"active_connection"]) {
   [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"active_connection"];
   [NSUserDefaults synchronize];
   // Send request to web-service
}
检索

[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"active_connection"];
[NSUserDefaults synchronize];
if(![[NSUserDefaults standardUserDefaults] boolForKey:@"active_connection"]) {
   [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"active_connection"];
   [NSUserDefaults synchronize];
   // Send request to web-service
}

我希望这对你有帮助。快乐编码

我认为在解决方案中会有各种各样的种族条件。单例解决方案可能有效,但需要对SudzC库进行一些修改。不过,谢谢你的建议,我一定会研究一下单例方法。欢迎!只是别忘了在这里提到什么对你有效,什么对你无效。因为这可能会在将来帮助一些编码人员。干杯