我在這裏發佈我自己的結果,也許他們會對某人有用。這是我對Parse源碼進行回顧後的工作原理的理解,我不能保證這是最終的文字或整個故事,但它符合事實。
解析現在是開源的,所以你至少可以去看看如果你有問題來確定發生了什麼。
Parse in github
解析保持的任務隊列,他們是嚴格按照它們被請求的順序進行處理。無論任務是在前臺(阻塞)還是在後臺請求(有或沒有回調),都是如此。此外,如果任務是查詢,引腳,保存等等,它們都排在任務列表中並不重要。任務列表保存在內存中,如果應用程序被暫停然後終止或在所有任務處理完成之前終止任務丟失。所以,如果解析沒有做任何事情,並且你要求一個pin或一個保存,它就會開始這個,很可能一切都會好起來的。
如果解析是忙碌的(按照我上面的描述),您的saveEventually在隊列末尾等待處理。在處理此任務之前,您有可能無法通過Parse記錄saveEventually。請注意,理解這一點非常重要,我的意思是看看任務 - 不完成任務 - 只是簡單地看看任務是什麼,並在saveEventually情況下記錄它。
我不一定認爲這是一個錯誤。我的問題是我正在查看saveEventually作爲數據庫提交。我知道這並不意味着它還在雲端,我只是推測,將它推送到雲端的請求在saveEventually返回時以非易失性方式存儲。一旦它被處理,它就像一個提交,它會最終到達雲端,但是你不能確定它已被編程處理(saveEventually回調完成時不記錄saveEventually)。
如果該應用程序被nuked那麼這樣做,用戶採取了一些行動,他們應該知道他們在做什麼。但是,如果您聲明您的應用程序有後臺任務,那麼您可以確保在用戶按下主鍵或移動到另一個應用程序時仍然有一個線程執行 - 我認爲他們有權執行此操作。我已經這樣做了,似乎可以防止我看到的數據丟失。我基本上確保處理任務列表,並且Parse已經記下了我所有的saveEventuallys,即使應用程序轉到了後臺。
iOS Background Execution
這是很難確定何時終止該線程。在我的應用程序中,我做了一個別針,並且成對保存了最終成果。該引腳確實有回調,所以我保持優秀的引腳數。當它達到零時,我等待一分鐘並關閉線程。這給了1分鐘來執行最終的saveEventually,這在測試中看起來已經足夠了。如果我在那時可以訪問互聯網,那麼保存最後的或下次運行的應用程序都會記錄下來。
我認爲你必須是相當沉重的Parse用戶才能看到這個問題。我有許多小數據對象分佈在不相關的不同表上。這會創建大量的查詢和備份引腳,如果您有一個表格或一個數據blob,您可以一次插入,則不會看到我描述的問題。
示例代碼(7Jan16編輯),按照註解請求
下面是我使用實現上述代碼的核心。如果你使用它,你將需要改變它。我建議閱讀上面的背景任務鏈接。後臺線程使應用程序保持活躍狀態,解析仍然可以處理其未完成的任務。
此代碼塊的意圖是提供一個輔助函數來跟蹤所有未解析的請求進行解析。它在調用時啓動後臺線程(startPinMonitor)。只有一個監視器被啓動,這在startPinMonitor中被檢查。我的代碼在UI線程上運行,否則在這裏可能需要一些同步邏輯。
- (void)store:(PFObject*) parseObject {
if (parseObject) {
if (self.outStandingPins == 0)
[self startPinMonitor];
self.outStandingPins++;
[parseObject pinInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
self.outStandingPins--;
if(!succeeded)
NSLog(@"Err : Pin failed?");
}];
[parseObject saveEventually];
}
}
這段代碼的意圖是保持應用程序運行,直到處理完所有剩餘的分析操作。它首先檢查監視器是否已經激活。 'checkPinStatus'方法每30秒調用一次,並在所有引腳都被處理時終止。突出引腳的日誌對檢測正確的操作非常有用。按Home鍵後,您應該能夠驗證應用程序仍在運行。如果您註釋掉'beginBackgroundTaskWithExpirationHandler'方法,您可以確定此代碼試圖實現的行爲差異。
-(void) startPinMonitor {
if (![self.myTimer isValid]) {
self.myTimer = [NSTimer scheduledTimerWithTimeInterval:30
target:self
selector:@selector(checkPinStatus)
userInfo:nil
repeats:YES];
self.myBackgroundTask = [[UIApplication sharedApplication]
beginBackgroundTaskWithExpirationHandler:^{
NSLog(@"Background tasks stopped");
}];
}
}
-(void) checkPinStatus {
NSLog(@"Current outStandingPins=%i", self.outStandingPins);
if (self.outStandingPins == 0) {
[self.myTimer invalidate];
[[UIApplication sharedApplication]
endBackgroundTask:self.myBackgroundTask];
}
}
如果你在殺死它之後再次啓動應用程序,數據是否最終被髮送到Parse?保存最終會完成它所說的內容,它最終會保存,而不是您稱之爲的分割秒。如果您在網絡連接完成之前終止應用程序,則會在下次應用程序運行時嘗試保存。 –
不,數據不會解析,無論您重新啓動應用後等待多久。數據丟失。就像我的用戶一樣,這就像任務沒有按計劃進行。不在本地數據存儲區或雲中(我可以通過解析門戶網站查看數據,看不到它)。 – pyrrhoofcam
我懷疑它可能是pinInBackground沒有完成,但是如果你強迫退出一個應用程序,你必須期望壞事會發生。如果用戶終止應用程序,即使是同步通話可能也無濟於事,它們實際上會在應用程序中途停止。 – Paulw11