【问题标题】:Prevent UIDocumentInteractionController PresentPreview from crashing my App防止 UIDocumentInteractionController PresentPreview 使我的应用程序崩溃
【发布时间】:2011-08-26 10:49:09
【问题描述】:

我正在尝试使用 UIDocumentInteractionController 预览文件。看起来很简单,但应用程序会随机崩溃并出现 SIGSEGV,并且在尝试了各种 hacks 几个小时后,我就是不明白缺少什么。

这段代码是从我的 UIViewController 类中调用的:

void Initialize ()
{
    mInteractionControllerDelegate = new  UIDocumentInteractionControllerDelegateClass(this, mFile);
    mInteractionController = UIDocumentInteractionController.FromUrl(NSUrl.FromFilename(mFile.Name));
    mInteractionController.Delegate = mInteractionControllerDelegate;
}

mInteractionControllerDelegate 和 mInteractionController 是我的视图控制器类的成员变量(我试过这样做,以确保事件不会在本应被 GCed 的变量上触发)

我在单击按钮时显示预览(带有 MPMoviePlayerViewController 的部分工作正常:

void btnShowTouchUpInside (object sender, EventArgs e)
{
    if (mFile.Name.EndsWith(".mpeg") || mFile.Name.EndsWith(".avi") || mFile.Name.EndsWith(".mpg"))
    {
        MPMoviePlayerViewController mp = new MPMoviePlayerViewController(NSUrl.FromString(mFile.VideoURL));
        this.PresentMoviePlayerViewController(mp);
    }
    else
    {
        InvokeOnMainThread(delegate {
            mInteractionController.PresentPreview(true);
        });;
    }
}

在某些情况下,预览会起作用(例如小 txt 文件:但我不确定文件大小 => 崩溃相关性)。但是,如果我尝试使用一些更大的 png 文件,例如(500 ko),我会看到预览几秒钟,然后应用程序崩溃并显示以下堆栈跟踪:

Stacktrace:

at (wrapper managed-to-native) MonoTouch.ObjCRuntime.Messaging.void_objc_msgSend (intptr,intptr) <IL 0x00024, 0xffffffff>
at MonoTouch.Foundation.NSObject/MonoTouch_Disposer.Drain (MonoTouch.Foundation.NSObject) [0x0002a] in /Users/plasma/Source/iphone/monotouch/Foundation/NSObject.cs:305
at (wrapper runtime-invoke) <Module>.runtime_invoke_void__this___object (object,intptr,intptr,intptr) <IL 0x00052, 0xffffffff>
at (wrapper managed-to-native) MonoTouch.UIKit.UIApplication.UIApplicationMain (int,string[],intptr,intptr) <IL 0x0009f, 0xffffffff>
at MonoTouch.UIKit.UIApplication.Main (string[],string,string) [0x00038] in /Users/plasma/Source/iphone/monotouch/UIKit/UIApplication.cs:26
at MonoTouch.UIKit.UIApplication.Main (string[]) [0x00000] in /Users/plasma/Source/iphone/monotouch/UIKit/UIApplication.cs:31
at DTS.Application.Main (string[]) [0x00000] in /Users/seb/Projects/DTS/DTS/Main.cs:14
at (wrapper runtime-invoke) <Module>.runtime_invoke_void_object (object,intptr,intptr,intptr) <IL 0x00050, 0xffffffff>

Native stacktrace:

0   DTS                                 0x000d1965 mono_handle_native_sigsegv + 343
1   DTS                                 0x0000ffb4 mono_sigsegv_signal_handler + 322
2   libSystem.B.dylib                   0x98a9f45b _sigtramp + 43
3   ???                                 0xffffffff 0x0 + 4294967295
4   ???                                 0x0d24837c 0x0 + 220496764
5   ???                                 0x077520d6 0x0 + 125116630
6   DTS                                 0x0000fd6f mono_jit_runtime_invoke + 1332
7   DTS                                 0x001ee239 mono_runtime_invoke + 137
8   DTS                                 0x0029e9ab monotouch_trampoline + 2527
9   Foundation                          0x0140e94e __NSThreadPerformPerform + 251
10  CoreFoundation                      0x00ea08ff __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
11  CoreFoundation                      0x00dfe88b __CFRunLoopDoSources0 + 571
12  CoreFoundation                      0x00dfdd86 __CFRunLoopRun + 470
13  CoreFoundation                      0x00dfd840 CFRunLoopRunSpecific + 208
14  CoreFoundation                      0x00dfd761 CFRunLoopRunInMode + 97
15  GraphicsServices                    0x0404c1c4 GSEventRunModal + 217
16  GraphicsServices                    0x0404c289 GSEventRun + 115
17  UIKit                               0x01ce0c93 UIApplicationMain + 1160
18  ???                                 0x09d540a3 0x0 + 164970659
19  ???                                 0x09d53e74 0x0 + 164970100
20  ???                                 0x09d53474 0x0 + 164967540
21  ???                                 0x09d532cc 0x0 + 164967116
22  ???                                 0x09d5341e 0x0 + 164967454
23  DTS                                 0x0000fd6f mono_jit_runtime_invoke + 1332
24  DTS                                 0x001ee239 mono_runtime_invoke + 137
25  DTS                                 0x001f0920 mono_runtime_exec_main + 669
26  DTS                                 0x001efd0a mono_runtime_run_main + 843
27  DTS                                 0x000a3c62 mono_jit_exec + 200
28  DTS                                 0x002a25eb main + 3838
29  DTS                                 0x000030c9 _start + 208
30  DTS                                 0x00002ff8 start + 40

Debug info from gdb:

/tmp/mono-gdb-commands.VWK7bK:1: Error in sourced command file:
unable to debug self

=================================================================
Got a SIGSEGV while executing native code. This usually indicates
a fatal error in the mono runtime or one of the native libraries 
used by your application.
=================================================================

最终线索:这是 UIDocumentInteractionControllerDelegateClass 的代码(根据 SO 上的其他问题创建):

public class UIDocumentInteractionControllerDelegateClass : UIDocumentInteractionControllerDelegate
{
    private UIViewController mViewController;
    private DTSVirtualFile mFile;

    public UIDocumentInteractionControllerDelegateClass(UIViewController viewController, DTSVirtualFile file)
    {
        mViewController = viewController;
        mFile = file;
    }

    public override UIViewController ViewControllerForPreview (UIDocumentInteractionController controller)
    {
        return mViewController;
    }

    public override UIView ViewForPreview (UIDocumentInteractionController controller)
    {
        return mViewController.View;
    }

    public override RectangleF RectangleForPreview (UIDocumentInteractionController controller)
    {
        return mViewController.View.Frame;
    }

    public override void DidEndPreview (UIDocumentInteractionController controller)
    {
        mFile.DeleteCopy();
    }

    public override void DidDismissOptionsMenu (UIDocumentInteractionController controller)
    {
        // TODO: Implement - see: http://go-mono.com/docs/index.aspx?link=T%3aMonoTouch.Foundation.ModelAttribute
    }

    public override void WillBeginPreview (UIDocumentInteractionController controller)
    {
        Console.WriteLine("WillBeginPreview");          
    }

    public override void WillBeginSendingToApplication (UIDocumentInteractionController controller)
    {
        // TODO: Implement - see: http://go-mono.com/docs/index.aspx?link=T%3aMonoTouch.Foundation.ModelAttribute
    }

    public override void WillPresentOpenInMenu (UIDocumentInteractionController controller)
    {
        // TODO: Implement - see: http://go-mono.com/docs/index.aspx?link=T%3aMonoTouch.Foundation.ModelAttribute
    }

    public override void WillPresentOptionsMenu (UIDocumentInteractionController controller)
    {
        // TODO: Implement - see: http://go-mono.com/docs/index.aspx?link=T%3aMonoTouch.Foundation.ModelAttribute
    }
}

当我调试时,我可以很好地跳过 PresentPreview,但之后它会立即崩溃。如果我评论 PresentPreview 行,不会崩溃。

任何指针,解决方案?

【问题讨论】:

  • 问题解决了吗?谢谢马可
  • 抱歉,Marco,问题暂时没有解决。由于我被分配到其他项目,该项目暂时搁置。如果项目再次开始,我将不得不解决它。也许单触更新会做?您是否尝试过 Monotouch 或 Xamarin 支持?如果您有解决方案,请在此处发布:)
  • 请用独立的测试用例填写错误报告。

标签: iphone xamarin.ios ios-simulator


【解决方案1】:

有一个 ABI bug 在方法返回结构(而非类)时会影响 MonoTouch,例如 RectangleF 并导致类似的崩溃。设备构建(使用不同的 ABO)不受此问题的影响。

一种解决方法是避免覆盖返回结构的方法,例如:

public override RectangleF RectangleForPreview (UIDocumentInteractionController controller)

【讨论】:

  • 很抱歉,我还没有接受您的解决方案。我无法立即对其进行测试(一天的时间不够用!),但我会尽快检查!
  • 不用担心,人们可以看到答案(即使不被接受)比没有答案更重要 :-) OTOH,如果可以的话,确认也会有帮助
  • 有时间来测试你的答案,这就成功了!感谢您的帮助,很高兴知道 Xamarin 的黑客在 SO 上很活跃。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-05-26
  • 2013-03-08
  • 2013-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多