2010-11-10 52 views
10

下面哪兩個應該用來確保所有遊標都關閉?成語關閉遊標

Cursor c = getCursor(); 

    if(c!=null && c.getCount()>0){ 
     try{ 
      // read values from cursor 
     }catch(..){} 
     finally{ 
      c.close(); 
     } 
    }//end if 

    OR 

    Cursor c = getCursor(); 
    try{ 
     if(c!=null && c.getCount()>0){ 
      // read values from cursor 
     }//end if 
    }catch(..){ 

    }finally{ 
     c.close(); 
    } 

編輯:
幾個問題:
1.我們需要調用close()在具有0計數的光標?
2.因爲在這種情況下,第一個習慣用法,close()永遠不會被調用。它假定對於沒有元素的遊標,遊標永遠不會被打開。這是一個有效的假設嗎?

請指教。

回答

13

也沒有,但第二個是最接近的。

  • 選項1不正確關閉 光標時getCount將()== 0
  • 選項2葉finally塊暴露在空指針異常

我會用:

Cursor c = getCursor(); 
try { 
    if(c!=null && c.getCount()>0){ 
     // do stuff with the cursor 
    } 
} 
catch(..) { 
    //Handle ex 
} 
finally { 
    if(c != null) { 
     c.close(); 
    } 
} 

...或者如果您希望光標經常爲空,您可以稍微調整一下它的標頭:

Cursor c = getCursor(); 
if(c != null) { 
    try { 
     if(c.getCount()>0) { 
      // do stuff with the cursor 
     } 
    } 
    catch(..) { 
     //Handle ex 
    } 
    finally { 
     c.close(); 
    } 
} 
+0

感謝您的回答! – 2010-11-11 17:19:31

+0

我不認爲使用getCount是一個好方法。如果你用戶moveToFirst,你可以得到更好的性能 – wangzhengyi 2014-09-13 02:03:04

+0

@wangzhengyi - 這是一個有效的點moveToFirst更高性能,並回答「結果集中是否有任何東西」的問題......但OP在他們的例子中使用了getCount(),所以我繼續在這裏。 – 2014-09-14 22:57:55

0

取決於你在抓什麼,但我會說第二個,以防萬一c.getCount()引發異常。

此外,一些縮進不會不妥去:)

0

我想說的第一個,主要是因爲第二個會嘗試調用c.close()即使cnull。此外,根據文檔,getCount()不會拋出任何異常,因此無需將其包含在try塊中。

+0

我們是否需要在計數爲0的遊標上調用close()?因爲在那種情況下,第一個習慣用法,close()永遠不會被調用。它假定對於沒有元素的遊標,遊標永遠不會被打開。這是一個有效的假設嗎? – 2010-11-10 12:56:17

+0

不需要。無論有多少物品,「光標」都需要關閉。 – Felix 2010-11-10 14:41:28

+0

您可以跳過'c.getCount()> 0'條件。這樣,你的光標總是會關閉的,你的'try'塊將不會做任何事情。 – Felix 2010-11-10 14:44:19

1

最佳做法是下面的一個:

Cursor c = null;  
try {   
    c = query(....);  
    while (c.moveToNext()) { // If empty or next to last record it returns false.  
     // do stuff..  
    } 
} finally { 
    if (c != null && !c.isClosed()) { // If cursor is empty even though should close it.  
    c.close(); 
    c = null; // high chances of quick memory release. 
} 
+0

我想知道在這種情況下是否最好的做法是將遊標設置爲空,因爲它是一個局部變量,GC應該足夠聰明來處理它了嗎? – Shyri 2017-01-19 14:31:40

3

這是更好的:

  • 不使用c.getCount() - 計數可能需要額外的工作數據庫,而不是需要
  • 在查詢塊之前初始化光標,因此未能創建查詢不會跟着最後的塊

代碼:

Cursor c = query(....); 
if (c != null) { 
    try {   
     while (c.moveToNext()) { // If empty or after last record it returns false.  
      // process row... 
     } 
    } 
    finally { 
     c.close(); 
    } 
} 

注意c可能會錯誤或空指針的情況下是空的。見https://stackoverflow.com/a/16108435/952135。儘管如此,我將在空遊標作爲錯誤的情況下報告空返回值。

+0

NPE是個問題,'query'可能返回'null'。 – Pin 2014-02-11 15:35:40

+0

我的意思是最後不需要'c!= null'檢查。如果查詢返回null,則NPE將失敗,與Hemant的代碼片段相同。我認爲'query()'方法永遠不會返回null。它應該創建查詢或拋出異常,在這種情況下,您不需要運行finally塊。這是正常的清理模式:創建資源...嘗試...做功...最後...清理...結束。如果創建失敗,則會報告。如果工作失敗或成功,最後進行清理。如果您瞭解,請刪除否定的投票。如果沒有,請寫。 – Oliv 2014-02-17 09:12:20

+1

它可以返回null,並在文檔中指定它(請參閱ContentResolver.query)。此外,請檢查此:http://stackoverflow.com/questions/13080540/what-c​​auses-androids-contentresolver-query-to-return-null – Pin 2014-02-18 10:13:39

-1

我想,我的回答是最好的一個:

Cursor cursor = null; 

    try { 
     cursor = rsd.rawQuery(querySql, null); 
     if (cursor.moveToFirst()) { 
      do { 
       // select your need data from database 
      } while (cursor.moveToNext()); 
     } 
    } finally { 
     if (cursor != null && !cursor.isClosed()) { 
      cursor.close(); 
      cursor = null; 
     } 
    } 
+0

如果這個答案不好,請告訴我爲什麼你認爲這個模型更糟糕 – wangzhengyi 2014-09-15 06:29:14

-1

我覺得@ skylarsutton的是問題的正確答案。但是,我想留下問題的代碼(答案中的任何代碼似乎都有一些缺陷)。請考慮使用我的代碼。

Cursor c = query(....); 
if (c != null) { 
    try {   
     //You have to use moveToFirst(). There is no quarantee that a cursor is located at the beginning. 
     for(c.moveToFirst();!c.isAfterLast();c.moveToNext()) { 
      // process row... 
     } 
    } 
    finally { 
     c.close(); 
    } 
}