0

我有一个 UIView,它有大约 60 个调用相同方法的按钮。单击按钮时,我通过这种方法打开不同的图像 - 我使用按钮标签来知道调用了哪个按钮以及要显示哪个图像。把它想象成一个画廊。

由于按钮的绘制很困难,我为此使用了 Interface Builder 并使用该 UIView 创建了一个 XIB。我只是将按钮拖到正确的位置,然后在事件 TouchUpInside 中将它们连接到我的方法。我用它来将视图添加到我的主视图中:

NSArray *xibContents = [[NSBundle mainBundle] loadNibNamed:@"Tour" owner:self options:nil];
UIView *tour = [xibContents lastObject];
[self.view addSubview:tour];

到目前为止一切顺利,乍一看效果很好。不幸的是,当应用程序使用了一段时间时,会出现一些问题。按钮仍然突出显示(所以它们仍然在这里!)但不再调用任何操作。那里只是亮点,但没有行动。

我不知道为什么,但不知何故垃圾收集器似乎破坏了 UIButton 目标。为什么?我该如何解决?

请注意,我没有以编程方式声明按钮。我认为将它们放在 IB 中就足够了。

我也找不到内存警告和 UIButton 目标的破坏之间的联系。内存警告确实出现在我的应用程序中,但大多数时候按钮仍然有效。

但它必须是一个垃圾收集器,因为这个错误完全是随机出现的。无法重现此错误,有时会在单击 5 次后发生,有时会在我的应用程序中花费 10 分钟后发生。

4

3 回答 3

1

当事情出错时重新设定目标是告诉它稍微大声或更坚持地做错误的事情。

你必须找到这个问题的原因。运行 Instruments (Build → Profile),选择 Allocations 模板并让您的应用启动。运行直到问题发生,然后按左上角的红色录制按钮停止在 Instruments 中录制。

在左侧列表中选择 Allocations 工具,在跨越时间线下方窗口的跳转栏中从 Statistics 更改为 Objects List。现在,每个要分配、保留、释放和释放的对象都有一行。单击小箭头可查看每个对象的历史记录。(严格来说,它是针对每个内存地址的;许多对象可以在应用程序运行时重用相同的内存地址。)您还可以按右上角的任何内容进行过滤,展开右侧边栏以获得有关所选内容的完整堆栈跟踪双击条目以与源代码相关联。

有很多关于 Instruments 的知识;检查文档并搜索网络。但这肯定会告诉你发生了什么,这样你就可以推断为什么会发生或没有发生什么。

于 2012-08-01T15:10:00.587 回答
1

您可以尝试像这样加载您的笔尖:

首先,在您的标头中创建一个 IBOutlet 属性。然后,当您创建 Nib 时,将该 UIView IBOutlet 连接到 Nib 中的顶级视图(所有内容都位于该视图上)。然后在您的实现中,像这样加载它:

 [[NSBundle mainBundle] loadNibNamed:@"Tour" owner:self options:nil];
 // self.view if in a view controller
 [self addSubview:self.tourView]; 

我的猜测是,可能是指向按钮的指针停止工作,但不是来自垃圾收集,因为这不会发生

并进行调试,您可以尝试以下操作:

 for (UIView* view in self.view.subviews)
     if ([view isKindOfClass:[UIButton class]])
     {
               if([self.view respondsToSelector:@selector(myIBAction:)]){
                   NSLog(@"it still sees the method");
                }

         NSLog(@"Button Rect: .2%f, .2%f, .2%f, .2%f", view.frame.origin.x, view.frame.origin.y, view.frame.size.width, view.frame.size.height);
      }

正如我在评论中提到的

于 2012-08-01T13:56:39.467 回答
1

这是将选择器添加到所有按钮的最简单方法。

for (UIView* view in self.view.subviews)
    if ([view isKindOfClass:[UIButton class]])
    {
         //Add selector
    }
于 2012-08-01T14:08:59.560 回答