简体   繁体   English

UIButton操作在一段时间后可能无法正常工作(可能是在进行一些垃圾回收之后)

[英]UIButton action doesn't work after some time (probably after some garbage collection)

I have a UIView with around 60 buttons who call the same method. 我有一个带有约60个调用相同方法的按钮的UIView。 When clicking the buttons, I open different images by this method - I use button tags to know which button was called and which image to display. 单击按钮时,我通过这种方法打开不同的图像-我使用按钮标签来知道调用了哪个按钮以及要显示哪个图像。 Think about it like a gallery. 像画廊一样思考它。

As the drawing of the buttons was difficult, I used the Interface Builder for that and created a XIB with that UIView. 由于绘制按钮很困难,因此我使用了Interface Builder并使用该UIView创建了XIB。 I simply dragged the buttons at the correct spots and connected them to my method at event TouchUpInside. 我只是将按钮拖动到正确的位置,然后在事件TouchUpInside上将它们连接到我的方法。 I used this to add the view to my main view: 我用它来将视图添加到主视图中:

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

So far so good, that works well at first glance. 到目前为止,到目前为止,效果很好。 Unfortunately, there is some issue when the app has been used for some time. 不幸的是,该应用程序使用了一段时间后出现了一些问题。 The buttons still highlight (so they are still here!) but there is no action called anymore. 这些按钮仍会突出显示(因此它们仍在这里!),但是没有再执行任何操作。 There just the highlight but no action. 只是亮点而没有动作。

I don't know why, but somehow the garbage collector seems to destroy the UIButton target. 我不知道为什么,但是垃圾回收器似乎以某种方式破坏了UIButton目标。 Why? 为什么? How can I fix that? 我该如何解决?

Please note I haven't declared the buttons programmatically. 请注意,我尚未以编程方式声明按钮。 I thought placing them in the IB would be enough. 我认为将它们放在IB中就足够了。

Also I couldn't find a connection between memory warnings and the destruction of the UIButton targets. 我也找不到内存警告和UIButton目标的破坏之间的联系。 Memory warnings do appear in my app, but most of the time the buttons still work then. 内存警告确实出现在我的应用程序中,但是大多数时候按钮仍然可以使用。

But it has to be a garbage collector because the bug comes up totally randomly. 但是它必须是垃圾收集器,因为该错误完全随机出现。 There is no way to reproduce this error, sometimes it happens after 5 clicks, sometimes after 10 minutes spending in my app. 无法重现此错误,有时会在单击5次后发生,有时会在我的应用中花费10分钟后发生。

You could try loading your nib like this: 您可以尝试像这样加载笔尖:

First, create an IBOutlet property in your header. 首先,在标题中创建IBOutlet属性。 Then when you create the Nib, wire that UIView IBOutlet to the top level view in the Nib (the one everything sits on). 然后,当您创建Nib时,将UIView IBOutlet连接到Nib中的顶级视图(所有内容都位于其中)。 Then in your implementation, load it like this: 然后在您的实现中,像这样加载它:

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

My guess is that it might be something where the pointer to the button stops working, but not from garbage collection, as that does not happen 我的猜测是,可能是按钮的指针停止工作的原因,但不是垃圾回收的原因,因为这不会发生

and to debug you might try something like: 并进行调试,您可以尝试如下操作:

 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);
      }

as I mention in the comments 正如我在评论中提到的

This is the easiest way to add selectors to all of your buttons. 这是将选择器添加到所有按钮的最简单方法。

for (UIView* view in self.view.subviews)
    if ([view isKindOfClass:[UIButton class]])
    {
         //Add selector
    }

Re-setting the targets when things go awry is telling it to do the wrong thing slightly louder or more insistently. 出现问题时重新设置目标,就是告诉它大声或更坚持地执行错误的操作。

You have to find the cause of this problem. 您必须找到此问题的原因。 Run Instruments (Build → Profile), choose the Allocations template and let your app startup. 运行仪器(构建→配置文件),选择分配模板,然后启动您的应用程序。 Run until the issue happens, then stop recording in Instruments by pressing the red recording button in the top left. 运行直到问题发生为止,然后按左上方的红色录音按钮停止在乐器中录音。

Select the Allocations instrument in the list at the left, change from Statistics to Objects List in the jump bar going across the window just below the timeline. 在左侧列表中选择分配工具,在时间线正下方的窗口中,从跳转栏中的“统计信息”更改为“对象列表”。 You now have a row for every object to be allocated, retained, released and deallocated. 现在,对于要分配,保留,释放和释放的每个对象都有一行。 Click the small arrow to see the history for each object. 单击小箭头以查看每个对象的历史记录。 (Strictly speaking, it's for each memory address; many objects can reuse the same memory address over the app's run.) You can also filter by anything in the top right, unfold the right-hand sidebar for a full stack trace on what's selected and double click an entry to correlate with the source code. (严格来说,它是针对每个内存地址的;许多对象可以在应用运行时重用同一内存地址。)您还可以按右上角的任何内容进行过滤,展开右侧边栏以获取有关所选内容的完整堆栈跟踪,双击一个条目将其与源代码相关联。

There's a lot to learn about Instruments; 关于乐器有很多东西要学习。 check the documentation and search the web. 查看文档并在网上搜索。 But this will definitely tell you what's happening, so that you may reason about why it's happening or what's not happening. 但是,这肯定会告诉您正在发生的事情,以便您可以推断发生原因或未发生原因的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM