Crashes with a slider (memory leak? SDK Bug?) - please help
I have a custom slider that overlays two images, using a mask (which is like 2 screens wide).
It works fine for a while and then gets slow and crashes.
I was sure it is a memory leak, but I cant find any. Then I read about a bug connected to touchesbegan and accelerometer, can it be that?
Or do to many actions stack up and the phone isnt able to handle it after a while? Is there a way to reduce number of actions I do the whole masking thing for?
Sorry to push this, but unfortunately I rarely get an answer here. Please help me to find out the reason:
- The question is to stupid
- The question is to sophisticated
- The question isnt formulated well (sorry, no native speaker)
- I should post code
- I just missed some secret rules I have to obey
- Other?
OK, first I defined all images and views in the "touchesbegan", now I define them all in the header file (see last code segment. I though that would help against possible leaks).
However it doesnt make difference at all. Moving the slider around the movement gets slower and slower and then the app crashes. The same happens if I just slide a little and close this viewcontroller and then open other instances and slide there.
Since your leak is in touchesBegan, it would only happen one time per touch. But since you are calling touchesBegan from touchesMoved, and since touchesMoved is called a LOT, you are therefore leaking a LOT. So removing that one line of code should significantly improve things. You still need to fix your leak, but there is no reason to call touchesBegan, and it is only compounding your problem.
Since your leak is in touchesBegan, it would only happen one time per touch. But since you are calling touchesBegan from touchesMoved, and since touchesMoved is called a LOT, you are therefore leaking a LOT. So removing that one line of code should significantly improve things. You still need to fix your leak, but there is no reason to call touchesBegan, and it is only compounding your problem.
But I want to draw the new mask every frame. And as I want to set the slider on a touch as well as on a move I need to call the masking code in both.
So I will need to release that tempMaskView. Will try to do that, will come back if it doesnt help.
the problem disappears (though the slider doesnt work as wanted anymore). Can this be a leak inside "CGImageCreateWithMask" or a performance problem?
Any idea how I can solve this?
It looks like you have quite a few leaks, actually.
Core Graphics types (i.e., the stuff that starts with CG-, like CGImage) have memory management rules that are analogous to Cocoa objects, though with slightly different naming conventions. You should take a look at the section on Memory Management in the Quartz 2D Programming Guide. In general, any Core Graphics function that contains "Create" or "Copy" returns a retained object which you are responsible for releasing (these rules are actually the same for other C-based interfaces, like Core Foundation, as well). For instance, if you look up CGImageCreateWithMask in the CGImage documentation, you'll see:
Quote:
Return Value
An image created by masking image with mask. You are responsible for releasing this object by calling CGImageRelease.
Since you don't appear to be releasing any of the old images before assigning the new ones, I believe you have several leaks that you need to fix. To do this, you'll have to go back through your code, and any time you're calling a function that returns a Core Graphics object, you need to determine whether you're responsible for releasing it (by following the naming conventions and checking the documentation), and if so, using CGImageRelease to clean up the old object before you reassign the pointer to a new one.
It looks like you have quite a few leaks, actually.
I appreciate your help very much, but I dont think it is a problem with missing releases. I had the releases locally first, now I have them in the view controller's dealloc. Just to get sure I changed my code "back" again:
I appreciate your help very much, but I dont think it is a problem with missing releases. I had the releases locally first, now I have them in the view controller's dealloc.
Whether are not the leaks are causing your performance problem is a separate issue, but you certainly are leaking memory if you're creating new objects each time touchesBegan is called and only releasing once in the dealloc; only the objects created the last time touchesBegan is called are being cleaned up properly. Don't forget that these objects
So I assume the "CGImageCreateWithMask" (with a 480x320 mask) is pretty slow and the phone isnt able to handle it.
Ignoring the leaks for a second, a 480 by 320 image requires over 600KB in memory, so it's not that surprising that it would be slow to allocate that much RAM, especially if you're calling it every time touchesMoved is fired. Does instruments show your object allocations and used memory shooting up as you're repeatedly creating the masks, even if it's not detecting leaks?
In any case, to debug performance issues, you might try running the CPU Sampler in instruments, as that will show where the app is spending most of its processing time.
Ignoring the leaks for a second, a 480 by 320 image requires over 600KB in memory, so it's not that surprising that it would be slow to allocate that much RAM, especially if you're calling it every time touchesMoved is fired. Does instruments show your object allocations and used memory shooting up as you're repeatedly creating the masks, even if it's not detecting leaks?
OK, sorry, I try to explain it very thoroughly.
The app so far has small leaks in other code segments, which arent critical and which I will kill later.
In this code segment there are no leaks of images and imageViews. Just when I use first code (calling the GImageCreateWithMask) there is one leak of 16Bytes, which occurs everytime touchesMoved is called and sums up quickly.
I am not that good with instruments but it seems it is a NFSNumber or stuff that doesnt get released.
As soon as I remove that call and just put the "mask" in the "masked" instead of the masked image there are no more leaks.
As far as I understand, if there were leaks because of "mask" or "masked" not being released properly they would show in both examples.
Quote:
That's not the direction I meant to go. Use your properties.
Sorry, I am old so I neither really understand what those properties are used for, if they have any relevance for this or what you are trying to tell me...I know you probably want me to find it out, but just a little more "captain obvious" would be nice.
I started with Apple Basic some 27 years ago. When I had put a value of 6 in variable mynumber it had the value of 6. I tried to understand that propery stuff, is there something like the variable remembering all values it ever had and so filling memory?
OK, so I tried a longer to understand that property stuff without success.
So I read a little more and found that for years properties werent available and people lived with it and as far as I understand, still live fine without.
So can you at least explain to me, why you trying to push me in that direction instead of telling me what I am doing wrong?
I did tell you what you are doing wrong. You are leaking that image view. If you would use your properties, then this wouldn't be an issue. Why are you declaring properties if you aren't going to use them?
And yes, properties are a relatively new addition to the language. What people did before was create the corresponding methods manually. So by adding them to the language, what Apple did was address a common problem. Such as what you are experiencing now.
"I'm too old" or "I saw it in a tutorial" are just lame excuses. If you want to do this stuff, then learn how it works. I don't know how to make that thread any simpler. It is far simpler than what you are attempting to do here in this thread. And it is a fundamental skill that you absolutely must understand in order to succeed on this platform. Until you understand memory management, you will continue to experience the kinds of problems that you are having right now.
Just to clarify, the real issue here isn't whether you use properties or not, the issue is making sure you understand how to properly manage memory. Using properties correctly will help to avoid introducing common retain/release bugs in your code, and it's definitely a good practice to follow -- after all, why do things manually and give yourself the chance to mess up if the built-in functionality is sufficient? That said, properties are not the be-all end-all of memory management; retained properties only work on Objective-C objects that support the NSObject protocol, so you can't rely on them when you need to manage memory for Core Foundation or Core Graphics objects, like you do here.
All that said: the performance issues and the memory leaks issues are not necessarily the same. Fixing the leaks that Brian and I have pointed out may make no difference in the way your app appears to behave (though it may prevent it from crashing when you run it for a really long time) and may not immediately address the issue you're trying to solve. In order to fix that issue, though, you have to isolate and understand it, and you can't possibly do that unless you completely understand what your code is currently doing. If your code has obvious bugs, you should fix them first, before you start changing things to address other issues, or you'll just end up compounding the problems.
You did not post any updated code showing that change, and the only code you've posted since I said it still had the same error. Also, as both I and ChrisL have pointed out, you are making several memory management errors just in this code. So it is therefore logical to assume that you are making memory management errors elsewhere as well.
I will say this, and I do not mean this as an insult in any way, if you are so confused about memory management that you cannot understand my properties thread, then you lack the skills to adequately identify and solve the problems you are having right now. There is no reason to assume that you are correctly using the instruments, and no reason to assume that you are correctly interpreting the results. The only skill you have at the moment is enough to identify "it gets slow and crashes". Using only what ChrisL and I have said so far - if you are correctly making the changes which you have not posted code to prove that yet - then the only change you can accurately assess is that it "doesn't get slow and crash anymore," or "it runs fine for a longer time, but still does eventually slow down and crash".
I don't need to run instruments to see problems in your code. You shouldn't, either. You are trying to use instruments to solve basic problems. That is not a good use of that tool.
then the only change you can accurately assess is that it "doesn't get slow and crash anymore," or "it runs fine for a longer time, but still does eventually slow down and crash".
Or, "the performance of the masking is still too slow, but I'm now certain it's not related to the memory leaks". Then you've at least narrowed down the possible cause.