Recently, when doing graffiti applet, found a few memory problems.
Doodle Demo This program opens after you go to the album to select the picture, then load a uiscrollview, then add a uiimageview on the Uiscrollview, and then set the selection image to ImageView image. When doodling, add a uiview to the Uiimageview, and the drawing will be done on this uiview.
The first one.
The problem now is that as soon as you start doodling, the memory will skyrocket, the increase is related to the size of the picture, see.
Picture size |
Pre-graffiti Memory |
Post-Graffiti Memory |
Memory gain |
21K |
4.9M |
8.1M |
3.2M |
104K |
4.5M |
29.5M |
25M |
563K |
6.9M |
35.1M |
28M |
Why do small pictures take up more memory before they doodle? Probably because the picture is small, the factors that affect memory more may be color, and so on. The 104K picture is black, while the 21K picture is light.
After constantly commenting on the code, I found that the memory spike was due to the fact that I called [self setneedsdisplay] in the Touchesmove function of UIView, that is, every process of moving the finger, the interface will be redrawn. Then you can explain why the memory gain is related to the size of the image, because the redraw interface is related to the size of the picture.
The current drawing principle is that because the redrawn function empties the last painting, it is necessary to repaint the previously drawn trajectory each time it is redrawn. For example, if you draw a line with 3 points, then move your finger to the 1th, draw the first point, the finger moves to the 2nd time, the first second point to draw, the finger moves to the third point, the first second point is painted; Similarly, when you draw the second line, Each point of the first line is redrawn every moment.
The advantage of this method is that the Undo function is very simple, as long as the last line is deleted from the record, and then re-painted, as if to undo the latest line, in fact, all the previous lines have been redrawn once.
The downside is obvious, time-consuming, CPU-intensive, and memory-depleted.
So now, only to find a can save the last painting content and can complete the undo function of the drawing method should be able to solve the problem, to be continued ...
A second question
In the study of the first question, the second problem is to select a picture from the album, the memory will go up after entering the preview interface (normal, because loading the picture), and then cancel, back to the album. At this time the memory does not change, there is a problem, it is supposed that the preview interface is no longer exist, why the memory will not be reduced to the same as before the image?
With Xcode's profile's leak tool, the reason for the memory leak is uistatusbarhideanimationparameters and uiimage.
Look at the UIImage first, check the code, and find a hidden memory leak of a deeper problem. Here is the code in the Viewcontroller that opens the album, which is called after the photo is selected. After selecting a photo, jump to the Viewcontroller of preview mode.
- (void) Imagepickercontroller: (Uiimagepickercontroller *) Picker Didfinishpickingmediawithinfo: (NSDictionary *) info{/*after selecting a picture, get the picture*/UIImage*image =[Info objectforkey:uiimagepickercontrolleroriginalimage]; /*Jump*/Qlmomentmainviewcontroller*viewcontroller =[[Qlmomentmainviewcontroller alloc] Initwithnibname:nil Bundle:nil]; viewcontroller.image = image; [Picker Dismissviewcontrolleranimated:yes Completion:^(void){}]; [Self.navigationcontroller Pushviewcontroller:viewcontroller Animated:yes]; [Viewcontroller release];}
Note The Red statement, first the image is not created by the first Viewcontroller (there is no method that contains alloc/new/copy/mutablecopy), so it is not required to release the image And then the second Viewcontroller does not have a method that contains alloc/new/copy/mutablecopy to create the image, so I naively thought that the second Viewcontroller did not need to be responsible for the release of the image. Therefore, the image is not disposed in the Dealloc function of the second Viewcontroller.
In fact, this is wrong, because viewcontroller.image = image; This line of code causes the reference count of image to be +1, which is the property we create ourselves, so in its implied setimage method, the image Retain once more. So the second Viewcontroller has the responsibility to release the Image property in Dealloc.
OK, so now as long as the second viewcontroller in the Dealloc in the release of the image, the problem is resolved.
A third question
The rest is the mysterious uistatusbarhideanimationparameters.
After continuous testing, it is found that the reason for this situation is that a memory leak occurs when you enter the album, do not select the diagram, and then come out after the cancellation .
At first I thought it was the reason I added in the project's Info.plist file to hide the status bar
However, there is a memory leak after the deletion. So only the internet for help.
I later found out that I rewrote the function of selecting photos
-(void) Imagepickercontroller: (uiimagepickercontroller *) Picker Didfinishpickingmediawithinfo: ( Nsdictionary *) Info
Without rewriting a function that cancels the selection of a photo
-(void) Imagepickercontrollerdidcancel: (uiimagepickercontroller *) Picker
In the description of the function, there is a sentence:
Your delegate ' s implementation of this method should dismiss the picker view by calling the Dismissmodalviewcontrolleranim Ated:method of the parent view controller.
Implementation of this method are optional, but expected.
OK, then rewrite this function and invoke [Picker dismissviewcontrolleranimated:YES Completion: ^ (void) {}] in the inside; To make the album interface disappear.
......
However, the problem still exists!
StackOverflow on this issue, someone suggested:
Maybe need to clear the delegate for your Uiimagepickercontroller? Delegates can prevent objects from being properly deallocated.
So I added a pick.delegate = nil in the callback function that finished selecting the photo or deselecting the photo.
......
However, the problem still exists!
Then, StackOverflow, someone said,
It ' s A bug in the SDK.
Then, under the official source of Apple-an open photo album to select the demo, found unexpectedly also appear this mysterious uistatusbarhideanimationparameters caused by the memory leak!
Finally, StackOverflow was suggested that
There is a know issue with the uiimagepickercontroller
memory leaks.
Apple recommend that's allocate and instantiate only one instance and store it somewhere for the life of T He application (whilst running is).
So at present, we can only declare picker as global variables, avoid multiple alloc and release.
Now the problem can only be solved here.
Summarize
1. Remember to release the property you created when necessary, not relying on alloc,new,copy and other words to decide whether or not to release.
2. Open the System album and then exit the memory leak will occur, this is the Apple bug?
IOS memory leaks