2011-09-22 51 views
1

在MonoTouch中,我需要處理NSSet中的每個對象。我的嘗試中,使用枚舉,如下:枚舉在MonoTouch中如何工作?

public override void ReturnResults (BarcodePickerController picker, NSSet results) 
{ 
    var n = results.Count; // Debugging - value is 3 
    results.Enumerate(delegate(NSObject obj, ref bool stop) 
    { 
     var foundCode = (obj as BarcodeResult); // Executed only once, not 3 times 
     if (foundCode != null) 
     { 
      controller.BarcodeScannedResult (foundCode); 
     } 
    }); 
// Etc 
} 

雖然該方法在結果與三個對象調用時,只有一個對象在委託處理。我本來期望這個代表被執行三次,但是我必須對它的工作原理有一個錯誤的想法。

無法找到任何文檔或示例。任何建議非常感謝。

回答

6

您必須將ref參數設置爲false。這將指示處理繼續列舉:

if (foundCode != null) 
{ 
    controller.BarcodeScannedResult (foundCode); 
    stop = false; // inside the null check 
} 

Here是ObjC相當於蘋果文檔。

+0

太棒了,作品魅力!非常感謝。 – BillF

+0

不客氣,很高興我幫了忙。請接受答案,以便其他StackOverflow用戶不會將其視爲未答覆。 –

0

或者你可以試試這個擴展方法,使其更容易..

public static class MyExtensions { 
    public static IEnumerable<T> ItemsAs<T>(this NSSet set) where T : NSObject { 
     List<T> res = new List<T>(); 
     set.Enumerate(delegate(NSObject obj, ref bool stop) { 
      T item = (T)(obj); // Executed only once, not 3 times 
      if (item != null) { 
       res.Add (item); 
       stop = false; // inside the null check 
      } 
     }); 

     return res; 
    } 
} 

然後,你可以這樣做:

foreach(BarcodeResult foundCode in results.ItemsAs<BarcodeResult>()) { 
    controller.BarcodeScannedResult (foundCode); 
} 

注:請記住,這將創建另一個列表,並複製一切對它來說效率較低。我這樣做是因爲匿名方法中不允許使用「yield return」,而我可以想到的另一種方法是將其作爲一個真正的枚舉數而不需要副本,這是更多的代碼。我處理的大多數曲目都很小,所以這並不重要,但是如果你有一個很大的曲目,這是不理想的。