简体   繁体   中英

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. 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. I simply dragged the buttons at the correct spots and connected them to my method at event 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. 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.

Also I couldn't find a connection between memory warnings and the destruction of the UIButton targets. 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.

You could try loading your nib like this:

First, create an IBOutlet property in your header. Then when you create the Nib, wire that UIView IBOutlet to the top level view in the Nib (the one everything sits on). 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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