我正在使用 Xamarin,在更新到 iOS 7 sdk 后,我的应用程序一直崩溃......我有一个函数,我从我的第一个 View Controller 传递到我的第二个 View Controller 作为一个简单的操作:
public void Dismiss()
{
try{
this.PresentedViewController.DismissViewController (false, null);
}
catch(Exception ex)
{
string filePath = Path.Combine(path, "log.txt");
File.AppendAllText(filePath,"\n" + DateTime.Now + "\tISSUE:\t Closing colletions detail tab...\n\n" + ex.Message + " " + ex.StackTrace);
}
}
现在应用程序即使在捕获到异常后也会崩溃。我的日志中打印的是:
Objective-C exception thrown. Name: NSInvalidArgumentException Reason: [UILabel backdropView:willChangeToGraphicsQuality:]: unrecognized selector sent to instance 0x18c8ee40 at (wrapper managed-to-native) MonoTouch.ObjCRuntime.Messaging:void_objc_msgSendSuper_bool_IntPtr (intptr,intptr, bool, intptr) at MonoTouch.UIKit.UIViewController.DismissViewController(Boolean animated, MonoTouch.Foundation.NSAction completionHandler) [0x00057] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIViewController.g.cs 747 at YltraRoute.MainViewController.CloseCollectionDetailTab()[0x00011]...
我什至不知道从哪里开始。那里没有太多帮助。
哦,它并不总是 [UILabel backdropView...它有时是 UIScrollViewPanGuestureRecognizer
所以我做了更多的搜索,看起来这可能是一个内存问题(对象已经被垃圾收集)。
我从 here 获得了该信息因为另一个版本的故障是:
Objective-C exception thrown. Name: NSInvalidArgumentException Reason: -[__NSCFType backdropView:willChangeToGraphicsQuality:]: unrecognized selector sent to instance 0x1eb3ad70
如果真是这样,我该如何处理。不可能已经发布了呈现 View Controller 吧?呈现的 View Controller 也在我的类中全局声明。
最佳答案
您不必使用 .DismissViewController
方法。我将尝试解释原因。
导航到新的 ViewController 时,您使用 PushViewController
方法。您在参数中创建的 View 被添加到堆栈中。所以,例如:
- 你有 ViewController A、B 和 C
- 您的主 ViewController 在 AppDelegate 中设置为 A
因此,当您打开您的应用时,堆栈看起来像这样:
| |
| |
| |
| A |
当用PushViewController
添加B和C时,它看起来像这样:
| |
| C |
| B |
| A |
现在,我听到你在问:但为什么我不必使用 DismissViewController
方法?好吧,还有另一种称为 PopToViewController
的方法。这用于导航到另一个已经在堆栈上的 ViewController。在示例中,您当前位于 ViewController C 中(因为它位于堆栈的顶部)。如果你想导航到 ViewController B,你可以搜索堆栈以确定它是否在那里,然后导航到它。这是它的一小段代码:
ViewController_B view_B = null;
foreach (var item in this.NavigationController.ViewControllers)
{
if (item is ViewController_B)
{
view_B = (ViewController_B)item;
}
}
if (view_B != null)
{
this.NavigationController.PopToViewController (view_B, true);
}
现在,您将弹出到 ViewController B,但由于它不是堆栈的顶部,因此它会丢弃(垃圾收集)ViewController C。这样,您就不需要手动关闭 C。
如果您想从 ViewController C 导航到 ViewController A,同样适用。相同的方法,但现在,它会丢弃 ViewController C 和 ViewController B。
但是,如果我要导航到的 ViewController 不存在怎么办?您可以在我刚刚粘贴的示例代码下方添加一条 else
语句,如下所示:
if (view_B != null)
{
this.NavigationController.PopToViewController (view_B, true);
}
else
{
this.NavigationController.PushViewController (new ViewController_D, true);
}
请注意,此方法仅在使用 ViewController 时有效,您在其中放置 UI(public class ViewController_B : UIViewController
)。
要添加如何从一个 ViewController 调用方法到另一个
(导航到它时)的问题的答案,有几个选项。我将列出我使用的方法。
当导航到另一个 ViewController
时,无论是使用 PopToViewController
还是使用 PushViewController
,Virtual
方法(来自抽象类 UIViewController
) ViewWillAppear
将始终被调用。如果您希望每次导航到 ViewController
时执行一次操作,您可以将它放在这个重写的方法中。
希望这些信息对您有所帮助。祝你好运!
爱与问候, 比约恩
关于c# - NSInvalidArgumentException 原因 - [xxxx 背景 View :willChangeToGraphicsQuality],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19869426/