它看起来确实足够无害。在我的应用程序委托(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_ACCESS
或 obj_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/