枚举在 MonoTouch 中如何工作?

发布于 2024-12-06 05:19:47 字数 609 浏览 0 评论 0原文

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

虽然调用该方法时结果中包含三个对象,但委托中仅处理一个对象。我本以为委托会被执行三次,但我对它的工作原理一定有错误的想法。

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

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

断舍离 2024-12-13 05:19:47

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

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

Here 是 Apple 文档中的 ObjC 等效项。

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.

不知所踪 2024-12-13 05:19:47

或者您可以尝试此扩展方法以使其更容易。

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

注意:请记住,这会创建另一个列表并将所有内容复制到其中,效率较低。我这样做是因为匿名方法中不允许“产量返回”,并且我可以想到的使其成为真正的枚举器而不需要副本的替代方法是更多的代码。我处理的大多数集合都很小,所以这并不重要,但如果你有一个大集合,这并不理想。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文