肯定看起来很无害。在我的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中没有多条布线或类似的东西。那里的一切看起来都很好,直到文件所有者的关系。)

线索欢迎/赞赏!

有帮助吗?

解决方案

问题出现在你的第一个代码片段中:你正在创建一个TipsViewController实例,保留它的视图,然后释放视图控制器 - 这将导致它被释放。所以现在按钮的 target 是指向解除分配的视图控制器的指针。

视图不保留其视图控制器,也不保留其委托或目标。

只要您希望显示视图,就必须保留视图控制器实例并保留 retain 属性—完成视图后,可以将其从父视图中删除,然后释放视图控制器。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top