2013-01-23 14 views
0

我有一個iOS應用程序,帶有一個tabbar和3個不同的UIViewControllers,每個標籤一個。該應用程序使用SudzC與C# .NET webservice接口從數據庫中提取數據。控制從多個UIViewControllers訪問webservice方法

有一個從所有三個視圖控制器調用的webservice方法,但我想強制只有一個視圖控制器可以在任何時間點調用該方法,並且在數據一直存在之前沒有其他視圖控制器可以調用它回。

我試圖通過在每個viewControllerAppDelegate限定NSLock,然後執行下面的代碼來解決這個問題:

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返回該處理程序被定義爲(截斷爲清楚起見)

-(void)handleRelogin: (id) result { 
    SDZLoginResult *loginResult = (SDZLoginResult*)result; 
    if(loginResult.Status) 
    { 
      SharedAppPersist.key = loginResult.key; 
    } 
    else 
    { 
      SharedAppPersist.key = @""; 
    } 
    [SharedAppDelegate.loginLock unlock]; 
} 

我的理解是,第一個UIViewController會得到一個鎖,而其他的會阻止長達30秒等待鎖定。然而,在極少情況下,不止一個viewController試圖在同一時間,我得到以下錯誤即刻訪問鎖:

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

誰能告訴我什麼,我做錯了什麼?我對C/C++中的鎖有很好的理解,但是這些Objective-C鎖已經難倒了。

回答

0

在我看來,你不應該爲這個簡單的情況使用鎖(這是「邪惡」)。

你可以嘗試使用的是一個NSOperationQueue,一次管理1個併發操作,然後讓視圖控制器排入他們的Web服務調用:操作隊列將保證一次只有一個操作被執行。 操作隊列的另一個優點是視圖控制器可以檢查隊列是否爲空,然後根據當前狀態決定是否排隊。 最後,您可以使用KVO觀察隊列狀態,以便每個視圖控制器可以在提交新請求之前對其進行簡單檢查。

與使用NSOperationQueue類似,另一種可能性是創建一個私有的GC​​D串行隊列,並再次入隊所有Web服務請求(包裝在一個塊中)。雖然GCD串行隊列比NSOperationQueues(IMHO)更直接,但它們不具備可觀察性和取消操作的可能性。

0

如果它只是你想要1次瀏覽一次訪問Web服務。你可以使用Singleton類。 下面是網絡上衆多例子之一的鏈接。 http://www.galloway.me.uk/tutorials/singleton-classes/

你也可以使用NSUserDefaults來存儲一個布爾值來通知你一個視圖是否使用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 
} 

我希望這可以幫助你。快樂編碼。

+0

我想NSUSerDefaults解決方案中會存在各種各樣的競爭條件。 Singleton解決方案可能會工作,但需要對SudzC庫進行一些修改。感謝您的建議,但我一定會考慮辛格爾頓方法。 –

+0

歡迎您!只是不要忘記在這裏提到什麼對你有用,什麼沒有。因爲這可能會在未來幫助一些同行的編碼人員。乾杯!! –