addKeyboardPanningWithActionHandler causing leak #16

Open
ghost opened this Issue Nov 27, 2012 · 11 comments

Comments

Projects
None yet
2 participants
@ghost

ghost commented Nov 27, 2012

I'm profiling my app with Instruments, and there seems to be a memory leak when using the following code:

__weak UITextView *weakTextView = mainTextView;
        [mainTextView addKeyboardPanningWithActionHandler:^(CGRect rect){
            CGRect convertedRect = [weakTextView convertRect:rect toView:weakTextView.superview];
            CGRect textRect = weakTextView.frame;
            textRect.size.height = convertedRect.origin.y;
            weakTextView.frame = textRect;
        }];

I'm using ARC. The leak is a NSMallockBlock. Instruments is saying the leak is coming from this line:

objc_setAssociatedObject(self,
                             &UIViewKeyboardDidMoveBlock,
                             keyboardDidMoveBlock,
                             OBJC_ASSOCIATION_COPY);

I can't seem to figure out what the problem is, but if I comment out all lines inside the actionHandler block, then the leak doesn't occur. Can you try to replicate this?

Owner

danielamitay commented Nov 27, 2012

Are you ever calling - (void)removeKeyboardControl;?

When you call addKeyboardPanningWithActionHandler:, it stores the block using objc_setAssociatedObject. To release this from memory by setting it to nil, you need to call - (void)removeKeyboardControl; when you are done with the keyboard panning functionality (when the view or view controller disappears).

@ghost

ghost commented Nov 27, 2012

Ya I'm doing that, I call it in the dealloc method of my view controller, and I can affirm it gets called.

Owner

danielamitay commented Nov 27, 2012

I am unable to reproduce. Could you send me an example?

@ghost

ghost commented Nov 27, 2012

Hmm to be honest the code I posted above is all I am doing. Perhaps I am doing some custom action somewhere else. Let me look into it a little more. Btw, I'm using Xcode 4.6 DP2 along with iPhone 6.1 simulator with the debug scheme.

Owner

danielamitay commented Nov 27, 2012

I mean in terms of the controller hierarchy.

The sample example doesn't suffer memory leaks, and neither did a project I made where I pushed a controller on and off of a UINavigationController. Are you sure that you are calling removeKeyboardControl on the same object on which you instantiated it?

@ghost

ghost commented Nov 27, 2012

Maybe I should add that all this is happening in a modal. After the modal is dismissed, the leak occurs.

@ghost

ghost commented Nov 27, 2012

I am sure removeKeyboardControl is being called properly, because if I don't, I get a BAD_ACCESS_ERROR due to not removing the text view from NSNotificationCenter. So it is being removed properly. The action handler block is the problem. If I remove all code from the action block, and just submit it empty, the leak does not occur.

@ghost

ghost commented Nov 27, 2012

Ok I've created a project that replicates the leak. All you have to is press the first button to open the modal, press anywhere to activate the text view, then play with the keyboard a little bit, and hit the dismiss button. After that, you should see the leak appear in the Leaks Instrument tool.

(testing with Xcode 4.6 DP2 on iPhone Simulator 6.1, and this shouldn't matter, but I've set my automatic snapshotting interval in the leak instrument to 3 seconds so it gets caught quickly)

https://github.com/mohabitar/KeyboardControlLeak

@ghost

ghost commented Nov 28, 2012

Have you had the chance to check out the code?

Owner

danielamitay commented Nov 28, 2012

I did indeed look at the code. Instruments is showing no memory leak for me in your example project, so I am unfortunately still unable to reproduce. There shouldn't be a memory leak the way it is set up, but the leak you are seeing certainly makes sense.

This might be related to Xcode 4.6 Developer Preview. I am still running on the 4.5 Stable.

The only recommendations I can make:

  • Change OBJC_ASSOCIATION_COPY to OBJC_ASSOCIATION_RETAIN, in DAKeyboardControl
  • Change __weak to __block before your block implementation
  • Do you have NSZombies enabled? If so, try turning it off.

I have the same problem. And I have try @danielamitay 's three advice, but no use. I also found this http://stackoverflow.com/questions/8710263/objective-c-associated-objects-leaking-under-arc .But I still don't know how to fix it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment