肯定看起来很无害。在我的App Delegate中,我检查 NSUserDefaults 是否有标志以显示启动时的提示。如果已设置,则在applicationDidFinishLaunching:
结束时,我执行此操作:
TipsViewController *vc = [[TipsViewController alloc]
initWithNibName:@“TipsView" bundle:nil];
[window addSubview:vc.view];
[vc release];
这个想法是暂时显示这个观点。 (请注意,它不是模态VC。此时没有导航控制器,而且此视图中没有导航栏。)
一旦该视图被取消,我们将把我们先占的 UITabBarController 的视图添加到窗口并转换到它,然后从主窗口中删除提示视图。我还没有把它解读为解雇点,因为,好吧,继续阅读。
我的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
,调整其大小以适应,并调整滚动视图的contentSize
以匹配。
当我运行应用程序时, TipsViewController 视图显示就好了。我甚至可以滚动提示文字。但是,当我在任何 UIButton 上触发内部触摸时,Xcode开始在源中植入我(我在每个 IBAction 处放置了一个断点)...然后使用EXC_BAD_ACCESS
或obj_stack_overflow
拯救
我将此与应用程序的其他部分进行了比较,其中包含VC,视图和按钮。它在各方面都是相同的,除了在这种情况下,我添加了VC的视图作为应用程序窗口的子视图,而不是将VC推送到导航控制器。此外,适用于iPhone OS的View Controller编程指南文档说这是公平的游戏:
如果您使用单个视图控制器 您的应用程序,您添加其视图 一个窗口而不是添加视图 控制器到标签栏或导航 控制器。
是的,我做有一个 UITabBarController 等待它,它有 UINavigationControllers (和其他VC)的标签。但是,如果显示提示视图,则选项卡栏控制器的视图 not 尚未添加到窗口中。目的是在我们完成提示后交换它。换句话说,出于所有意图和目的,我们暂时表现得像我们有一个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中没有多条布线或类似的东西。那里的一切看起来都很好,直到文件所有者的关系。)
线索欢迎/赞赏!
答案 0 :(得分:8)
问题出现在你的第一个代码片段中:你正在创建一个TipsViewController实例,保留它的视图,然后释放视图控制器 - 这将导致它被解除分配。所以现在按钮的target
是指向解除分配的视图控制器的指针。
视图不保留其视图控制器,也不保留其委托或目标。
只要您希望显示视图,就必须保留视图控制器实例 - 可能保留在retain
属性中。完成视图后,可以将其从父视图中删除,然后释放视图控制器。