它看起来确实足够无害。在我的 App 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 。我还没有达到观点驳回点,因为,好吧,继续阅读。
我的 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 调用的声明和定义。现在他们两个什么都不做。第三个更改提示
text
,调整其大小以适合,并调整滚动 View 的 contentSize
以匹配。当我运行应用程序时, TipsViewController View 显示得很好。我什至可以滚动浏览提示文本。但是,当我在任何 UIButton 上触发 touch-up-inside 时,Xcode 开始将我置于源代码中(我在每个 IBAction 处放置了一个断点)……然后使用
EXC_BAD_ACCESS
或 obj_stack_overflow
退出.我将此与应用程序的其他部分进行了比较,其中我有一个 VC、一个 View 和按钮。它在各个方面都是相同的,除了在这种情况下,我添加了一个 VC 的 View 作为应用程序窗口的 subview ,而不是将 VC 推送到导航 Controller 上。此外, View Controller Programming Guide for iPhone OS 文档说这是公平的游戏:
确实,我确实有一个 UITabBarController 在等待,它有带有 UINavigationControllers (和其他 VC)的选项卡。但是,如果正在显示提示 View ,则标签栏 Controller 的 View 尚未添加到窗口中。目的是在我们显示提示后将其换入。换句话说,出于所有意图和目的,我们暂时表现得好像我们有一个 VC 在玩。之后,我们切换到选项卡栏并拆除尖端 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 ——这将导致它被释放。所以现在按钮的 target
是一个指向释放的 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/