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
}

メソッドは結果として 3 つのオブジェクトで呼び出されますが、デリゲートで処理されるオブジェクトは 1 つだけです。デリゲートが 3 回実行されることを期待していましたが、それがどのように機能するかについて間違った考えを持っているに違いありません。

ドキュメントや例が見つかりません。どんな提案でも大歓迎です。

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 に答える