【问题标题】:Monotouch random crash in native code using UITableView使用 UITableView 在本机代码中的 Monotouch 随机崩溃
【发布时间】:2012-07-17 15:32:44
【问题描述】:

请帮帮我,我做错了什么。

我使用示例中的BubbleCellBubbleElement。 由于未知原因,应用程序有时会在本机代码中崩溃。 如果我不使用DequeueReusableCell,我会尝试纠正这种情况,并始终创建一个新的BubbleCell。 另外,如果构造函数BubbleElement 传递一个字符串常量作为标题,而不是对象字段,问题就会消失。

堆栈跟踪:http://pastebin.com/KAYzpHDk


问题比看起来更深。 您的建议没有帮助,应用程序仍然崩溃。

我创建了一个单独的项目,只保留了显示问题所需的最少代码。 这个问题在某种程度上与 System.Json 相关......也许吧。

这是该项目的存档: https://dl.dropbox.com/u/63074515/BubbleNativeCrash.zip

动作顺序: 1)打开项目 2)编译运行模拟器无需调试(配置Debug|iPhoneSimulator) 3) 在第一个视图中单击 horse1 4)在出现的列表中,上下滚动整个项目几次 5)在我的情况下,在这个阶段我们崩溃了......(堆栈跟踪:http://pastebin.com/KAYzpHDk

如果不是立即失败,可以返回联系人列表,反之亦然,甚至一次几次。 失败的速度取决于聊天中的消息数量。

现在是有趣的部分。 如果在 ChatViewController.cs 中注释第 406 行并取消注释第 407 行,问题就会完全消失(或者我无法在合理的时间内重复它):

// string messageText = msg.MessageText ?? string.Empty;
string messageText = "Hello, World!!!";

也就是说,将一个常量字符串传递给 BubbleElement 构造函数。 在那之后,我认为问题不会重复。

我试图让所有内容保持原样,但使用 Json 删除工作 - 问题消失了。 仅当 BubbleElement 从 JsonValue 读取字符串时出现问题(IM\IMMessage.cs 在第 36 行)。 即使在 IMMessage.cs 中有为 MessageText 设置常量字符串 - 问题也消失了。

我做错了什么? :)

附言对不起我的英语......它由谷歌翻译提供支持。

【问题讨论】:

    标签: ios uitableview garbage-collection xamarin.ios monotouch.dialog


    【解决方案1】:

    您没有保留对从GetCell 返回的托管 实例的任何引用。因此,一旦方法返回,GC 可以(并且将)收集 托管 实例,而 本机 实例将继续存在(因为它在 iOS 内部被引用)。

    当您使用 UITableViewCell 时,这可以正常工作,因为所有状态都保存在 native 实例中。但是,如果您从它继承并添加自己的 ma​​naged 字段,则情况并非如此。在这种情况下,您将无法访问托管状态,因为它不存在(您将拥有的实例将不是您创建的实例)。

    解决此问题的简单方法是保留对您创建的 BubbleCell 的引用,例如在列表中,因此 GC 不会收集它们。

        static List<BubbleCell> cell_cache = new List<BubbleCell> ();
    
        public override UITableViewCell GetCell(UITableView tableView)
        {
            var cell = tableView.DequeueReusableCell(isLeft ? BubbleCell.KeyLeft : BubbleCell.KeyRight) as BubbleCell;
            if (cell == null) {
                cell = new BubbleCell(isLeft);
                cells_cache.Add (cell);
            }
            cell.Update(Caption);
            return cell;
        }
    

    一旦不再需要单元格(例如关闭UITableView 时),请不要忘记清除列表。

    根据额外信息更新

    cell_cache 必须是 static 否则将无济于事(我的错误,已在上面修复)保持引用有效。但是,正如您所发现的,这不是解决这种情况的方法(来源显示单元格可以重复使用)。

    OTOH 该问题与使用 JSON 无关。使用相同的 string 消息(例如来自数组)会导致相同的崩溃。这有点奇怪,我会进一步研究这个......

    最终更新

    事实证明,对 CreateResizableImage 的调用可以访问 iOS bug。解决方法是使用较旧的StretchableImage API。该问题已(重新)提交给 Apple。

    【讨论】:

    • 谢谢...我真的很期待结果。我尝试将静态用于_cellCache,没有区别。
    • 原始 BubbleCell 示例存在相同的问题(使用相同字符串的子集)。错误填充@bugzilla.xamarin.com/show_bug.cgi?id=6177
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-11
    • 2014-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多