DAKeyboardControl
DAKeyboardControl copied to clipboard
addKeyboardPanningWithActionHandler causing leak
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?
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).
Ya I'm doing that, I call it in the dealloc method of my view controller, and I can affirm it gets called.
I am unable to reproduce. Could you send me an example?
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.
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?
Maybe I should add that all this is happening in a modal. After the modal is dismissed, the leak occurs.
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.
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
Have you had the chance to check out the code?
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_COPYtoOBJC_ASSOCIATION_RETAIN, inDAKeyboardControl - Change
__weakto__blockbefore your block implementation - Do you have
NSZombiesenabled? 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.