2014-10-07 63 views
0

我發現了很多有關這個話題的帖子,不過我會繼續做一些錯誤......爲什麼PFQuery.cancel()作爲parse.com-Framework的一部分不起作用?

創建query,PFQuery的實例後,該請求被實現爲query.findObjects()(運行在後臺線)。在該請求期間,我無法取消像我期望的方法query.cancel()那樣的過程。

場景:缺少Internet連接,query.findObjects()嘗試連接,失敗,再次嘗試。我實現了query.cancel(),它在請求首次失敗時執行(在所提及的點執行的if objects == nil中),仍然需要第二次嘗試。第二次嘗試後 - 每個人都需要15秒左右 - 失敗,但不會觸發第三次。

爲什麼會發生這種情況,爲什麼在調用query.cancel()時過程不會中斷?

感謝您的幫助!

編輯1:一些代碼

func getPost() { 

    let queue = dispatch_queue_create("SerialBgQueue", DISPATCH_QUEUE_SERIAL) 

    dispatch_async(queue, { 

     var query = PFQuery(className: "Post") 

     var objects = query.findObjects() 

     if objects != nil { 

      // do something 

     } else { 

      println("This part is executed now") 

      // doesn't stop the ongoing (second) connection attempt: 
      query.cancel() 

      // do something 

      return 
     } 
    }) 
} 

編輯2:這是日誌 - 對我來說,它看起來像嘗試的第二束,檢查日誌(2企圖,3,4,...然後開始再次2,3,4 ...)。 else {-部分在中間執行一次,最後一次執行第二次。之後,一切都停止了,不再有「企圖」。

2014-10-08 13:37:10.104 Instagram[9210:391955] Error: Error Domain=NSURLErrorDomain Code=-1009 "The Internet connection appears to be offline." UserInfo=0x7fe708c545c0 {NSUnderlyingError=0x7fe708c53020 "The Internet connection appears to be offline.", NSErrorFailingURLStringKey=https://api.parse.com/2/find, NSErrorFailingURLKey=https://api.parse.com/2/find, _kCFStreamErrorDomainKey=12, _kCFStreamErrorCodeKey=8, NSLocalizedDescription=The Internet connection appears to be offline.} (Code: 100, Version: 1.3.0) 

2014-10-08 13:37:10.105 Instagram[9210:391952] Network connection failed. Making attempt 2 after sleeping for 1.092226 seconds. 

2014-10-08 13:37:11.311 ... (Code: 100, Version: 1.3.0) // same Error like in the very first line 

2014-10-08 13:37:11.312 Instagram[9210:391945] Network connection failed. Making attempt 3 after sleeping for 2.184451 seconds. 

2014-10-08 13:37:13.704 ... (Code: 100, Version: 1.3.0) 

2014-10-08 13:37:13.704 Instagram[9210:391952] Network connection failed. Making attempt 4 after sleeping for 4.368902 seconds. 

2014-10-08 13:37:18.514 ... (Code: 100, Version: 1.3.0) 

2014-10-08 13:37:18.514 Instagram[9210:391952] Network connection failed. Making attempt 5 after sleeping for 8.737804 seconds. 

2014-10-08 13:37:27.257 ... (Code: 100, Version: 1.3.0) 

This part is executed now 

2014-10-08 13:37:27.265 ... (Code: 100, Version: 1.3.0) 

2014-10-08 13:37:27.266 Instagram[9210:392183] Network connection failed. Making attempt 2 after sleeping for 1.387503 seconds. 

2014-10-08 13:37:28.792 ... (Code: 100, Version: 1.3.0) 

2014-10-08 13:37:28.793 Instagram[9210:392202] Network connection failed. Making attempt 3 after sleeping for 2.775006 seconds. 

2014-10-08 13:37:31.843 ... (Code: 100, Version: 1.3.0) 

2014-10-08 13:37:31.844 Instagram[9210:392205] Network connection failed. Making attempt 4 after sleeping for 5.550011 seconds. 

2014-10-08 13:37:37.401 ... (Code: 100, Version: 1.3.0) 

2014-10-08 13:37:37.401 Instagram[9210:392202] Network connection failed. Making attempt 5 after sleeping for 11.100023 seconds. 

2014-10-08 13:37:49.050 ... (Code: 100, Version: 1.3.0) 

This part is executed now 
+0

你能發佈代碼嗎? – danh 2014-10-07 19:12:06

+0

@danh當然! – 2014-10-07 22:14:10

+0

「(第二次)連接嘗試」是什麼意思? 'query'之後是否有另一個查詢? – 2014-10-07 23:24:11

回答

1

我想你對findObjects()的假設是不正確的。該變體阻塞了它啓動的線程(後臺線程在發佈的情況下),並且在成功或失敗時返回。當您撥打取消電話時,您的代碼中沒有任何內容可以取消。

典型取消模式是當代碼開始在不同的線程查詢,然後決定其需要取消,這樣(在Objective-C ...對不起)

PFQuery *query = [PFQuery queryWithClassName:@"Post"];  
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) { 
    // this block might get called more than once, depending on the cache policy 
    // but it will be called with an error only once and stop after that 
    // (no second attempt that I know about) so as far as I can tell, there's 
    // no reason to ever call cancel here. 
}]; 

說你別不希望查詢花費超過10秒的時間。然後...

[query performSelector:@selector(cancel) withObject:nil afterDelay:10.0]; 
+0

我必須保留'findObjects()',因爲稍後會有更多代碼需要等待查詢完成但不能寫入'... inBackgroundWithBlock'部分(至少在我目前的經驗級別)。無論如何,我會接受你的意見並繼續努力。也許我的編輯2與日誌給出了一些進一步的信息。 – 2014-10-08 11:59:23

+0

我需要在我的示例中實現performSelector,以便獲得期望的效果? – 2014-10-08 22:39:26

+0

如果您使用... inBackgroundWithBlock種類的查找,那麼performSelector會有意義,然後您可以將該行放在它之後。如果解析在其重試時真的阻塞了這個後臺線程,你可以保留一個標誌並取消iOS線程。見例如這裏http://stackoverflow.com/questions/10066897/objective-c-cancel-a-dispatch-queue-using-ui-event – danh 2014-10-08 23:04:54