1

在 MonoTouch 中,我需要处理 NSSet 中的每个对象。我使用 Enumerate 的尝试如下:

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
}

尽管在结果中使用三个对象调用该方法,但在委托中只处理了一个对象。我原以为委托会被执行三遍,但我对它的工作原理肯定有错误的想法。

找不到任何文档或示例。任何建议都非常感谢。

4

2 回答 2

6

您必须将ref参数设置为 false。这指示处理程序继续枚举:

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

是 Apple 文档中的 ObjC 等价物。

于 2011-09-22T11:17:27.247 回答
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”,而且我能想到的使其成为没有副本的真正枚举器的替代方法是更多的代码。我处理的大多数套装都很小,所以这无关紧要,但如果你有一个大套装,这并不理想。

于 2012-08-30T06:00:56.490 回答