iphone - “Normal” UIButton 导致 obj_stack_overflow 或 EXC_BAD_ACCESS 异常

标签 iphone uiviewcontroller stack-overflow uibutton uiwindow

它看起来确实足够无害。在我的应用程序委托(delegate)中,我检查 NSUserDefaults 是否有一个标志以在启动时显示提示。如果已设置,则在 applicationDidFinishLaunching: 的末尾,我将执行以下操作:

TipsViewController *vc = [[TipsViewController alloc]
  initWithNibName:@“TipsView" bundle:nil];
[window addSubview:vc.view];
[vc release];

这个想法是暂时显示这个 View 。 (请注意,它不是模态 VC。此时没有导航 Controller ,而且此 View 中也没有导航栏。)

一旦该 View 被关闭,我们将把抢占的UITabBarController View 添加到窗口中并转换到它,然后从主窗口中删除提示 View 。我还没有到达 View 消除点,因为,好吧,继续阅读。

我的 TipsView 的 VC 或多或少是这样连接的:

UIView -> view -> File’s Owner (TipsViewController)
  UIImageView -> background image
  UIView -> tipView -> File’s Owner
    UIImageView -> background image
    UIScrollView
      UILabel (tip text)
    UIButton -> touch-up-inside -> -(IBAction)button1:
    UIButton -> touch-up-inside -> -(IBAction)button2:
    UIButton -> touch-up-inside -> -(IBAction)button3:

源代码包含所有三个 IBAction 调用的声明和定义。现在他们两个什么也不做。第三个更改提示文本,调整其大小以适应,并调整 ScrollView 的contentSize以匹配。

当我运行应用程序时,TipsViewController View 显示得很好。我什至可以滚动浏览提示文本。然而,当我在任何 UIButton 上触发内部修饰时,Xcode 开始将我植入源代码中(我在每个 IBAction 处放置了一个断点)...然后使用 EXC_BAD_ACCESSobj_stack_overflow 退出。

我将其与应用程序的其他部分进行了比较,其中有 VC、 View 和按钮。它在各方面都是相同的,除了在本例中,我添加了 VC 的 View 作为应用程序窗口的 subview ,而不是将 VC 推送到导航 Controller 。此外,iPhone OS View Controller 编程指南文档说这是公平的游戏:

If you use a single view controller in your application, you add its view to a window instead of adding the view controller to a tab bar or navigation controller.

确实,我确实有一个UITabBarController在伺机而动,它有带有UINavigationControllers(和其他VC)的选项卡。但是,如果显示提示 View ,则标签栏 Controller 的 View 尚未添加到窗口中。目的是在我们展示完提示后将其交换。换句话说,无论出于何种意图和目的,我们暂时表现得好像我们只有一个风险投资家在玩。之后,我们切换到标签栏并撕下提示VC。

也许我做错了什么?有没有更好的办法? (“一定有更好的方法!”)

示例堆栈跟踪:

#0  0x992b6f52 in objc_exception_throw
#1  0x302d6ffb in -[NSObject doesNotRecognizeSelector:]
#2  0x3026e056 in ___forwarding___
#3  0x3024a0a2 in __forwarding_prep_0___
#4  0x308f79d1 in -[UIApplication sendAction:to:from:forEvent:]
#5  0x309598b1 in -[UIControl sendAction:to:forEvent:]
#6  0x3095bad2 in -[UIControl(Internal) _sendActionsForEvents:withEvent:]
#7  0x3095a81e in -[UIControl touchesEnded:withEvent:]
#8  0x30910fdf in -[UIWindow _sendTouchesForEvent:]
#9  0x308faecb in -[UIApplication sendEvent:]
#10 0x309013e1 in _UIApplicationHandleEvent
#11 0x32046375 in PurpleEventCallback
#12 0x30245560 in CFRunLoopRunSpecific
#13 0x30244628 in CFRunLoopRunInMode
#14 0x32044c31 in GSEventRunModal
#15 0x32044cf6 in GSEventRun
#16 0x309021ee in UIApplicationMain
#17 0x00002888 in main at main.m:14

正如你从跟踪中看到的,我们最终到达了 doesNotRecognizeSelector: ...除了我可以清楚地看到我的提示 VC 源代码中的方法。另外,它们都已连接好。 (IB 中没有多重接线或类似的情况。一切看起来都很好,包括文件所有者关系。)

欢迎提供线索/赞赏!

最佳答案

问题就在你的第一个代码片段中:你正在创建一个 TipsViewController 的实例,保留它的 View ,然后释放 View Controller ——这将导致它被释放。所以现在按钮的目标是指向已释放 View Controller 的指针。

View 不保留其 View Controller ,也不保留其委托(delegate)或目标。

只要您希望显示 View ,您就必须保留 View Controller 实例(可能在 retain 属性中)。当您完成 View 后,您可以将其从其父 View 中删除,并释放 View Controller 。

关于iphone - “Normal” UIButton 导致 obj_stack_overflow 或 EXC_BAD_ACCESS 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1421793/

相关文章:

iphone - 关于xcode中浮点值的问题

iphone - 无法完全拆解 AVAudioPlayer

uiviewcontroller - 切换到另一个 View ,但保留在导航 Controller 中

iphone - 引用从中添加 subview 的类

ios - -[UIViewController_keyboard] : unrecognized selector sent to instance 0x7b731ac0

在 JPanel 中实现 Runnable 时出现 java.lang.StackOverflowError - Java Swing

c - 特定情况下的段错误

iphone - 挂断智能手机后记录通话

iphone - iOS 应用程序中的代码重用

c++ - 控件的 CWnd::DefWindowProc 上 Stackoverlow 异常的原因是什么