Question

In MonoTouch I need to process each object in an NSSet. My attempt, using Enumerate, is as follows:

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
}

Although the method is invoked with three objects in results, only one object is processed in the delegate. I would have expected the delegate to be executed three times, but I must have the wrong idea of how it works.

Unable to find any documentation or examples. Any suggestion much appreciated.

Was it helpful?

Solution

You have to set the ref parameter to false. This instructs the handler to continue enumerating:

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

Here is the ObjC equivalent from Apple documentation.

OTHER TIPS

Or you could try this extension method to make it easier..

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;
    }
}   

Then you can do something like:

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

Note: Keep in mind this creates another list and copies everything to it, which is less efficient. I did this because "yield return" isn't allowed in anonymous methods, and the alternative ways I could think of to make it a real enumerator without the copy were much much more code. Most of the sets I deal with are tiny so this doesn't matter, but if you have a big set this isn't ideal.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top