IPhone SDK: Does 3.0 free up image cache? Because 2.2.1 does not!

I am creating an iPhone application that includes several buttons that enliven the same UIImageView. It works well in the simulator (for example, in almost all applications), but when it comes to the device, it plays the animation well, but when you press the buttons again, the application closes. So far I have implemented two buttons. This is what happens when they are pressed. Ok, I have 44 MB of RAM available when the application starts. Then, when I press the first of the two buttons that start the animation, the available memory drops to 31 and goes up to 32, then when I press the second button, the available memory goes down to 9, then goes up to 24, and then weirdly goes down to 10 slowly. If the first one is pressed, then the available memory rises to 14 MB. When these buttons are pressed again, the application memory decreases to 4 - 3 MB and ends. There are no leaks in the devices. Here is my code that can determine where the memory issue is hiding. (BTW, I am still developing on 2.2.1, because if I upgrade to 3.0, I will not be able to test my applications on the device, since I have not yet registered with the Apple developer program, and I followed the online tutorial to get applications on a device that works only with 2.2.1)

@synthesize 123pig; - (IBAction)startClick:(id)sender{ animationTimer = [NSTimer scheduledTimerWithTimeInterval:(1.00/30.00) target:self selector:@selector(tick) userInfo:nil repeats:NO]; 123pig.animationImages = [NSArray arrayWithObjects: [UIImage imageNamed: @"123pigapple0001.png"], [UIImage imageNamed: @"123pigapple0002.png"], [UIImage imageNamed: @"123pigapple0003.png"], [UIImage imageNamed: @"123pigapple0004.png"], [UIImage imageNamed: @"123pigapple0005.png"], [UIImage imageNamed: @"123pigapple0006.png"], [UIImage imageNamed: @"123pigapple0007.png"], [UIImage imageNamed: @"123pigapple0008.png"], [UIImage imageNamed: @"123pigapple0009.png"], [UIImage imageNamed: @"123pigapple0010.png"], [UIImage imageNamed: @"123pigapple0011.png"], [UIImage imageNamed: @"123pigapple0013.png"], [UIImage imageNamed: @"123pigapple0014.png"], [UIImage imageNamed: @"123pigapple0015.png"], [UIImage imageNamed: @"123pigapple0016.png"], [UIImage imageNamed: @"123pigapple0017.png"], [UIImage imageNamed: @"123pigapple0018.png"], [UIImage imageNamed: @"123pigapple0019.png"], [UIImage imageNamed: @"123pigapple0020.png"],nil]; [123pig setAnimationRepeatCount:1]; 123pig.animationDuration =.7; [123pig startAnimating]; } - (void)tick{ [self animatePig]; } - (void)animatePig{ UIImage *pigImage13=[UIImage imageNamed:@"123pigapple0020.png"]; if(123pig.image == pigImage13) 123pig.image = pigImage13; else 123pig.image = pigImage13; } - (IBAction)startClick1:(id)sender{ animationTimer1 = [NSTimer scheduledTimerWithTimeInterval:(1.00/30.00) target:self selector:@selector(tick1) userInfo:nil repeats:NO]; 123pig.animationImages = [NSArray arrayWithObjects: [UIImage imageNamed: @"123pig0015.png"], [UIImage imageNamed: @"123pig0016.png"], [UIImage imageNamed: @"123pig0017.png"], [UIImage imageNamed: @"123pig0018.png"], [UIImage imageNamed: @"123pig0019.png"], [UIImage imageNamed: @"123pig0020.png"], [UIImage imageNamed: @"123pig0021.png"], [UIImage imageNamed: @"123pig0022.png"], [UIImage imageNamed: @"123pig0023.png"], [UIImage imageNamed: @"123pig0024.png"], [UIImage imageNamed: @"123pig0025.png"], [UIImage imageNamed: @"123pig0026.png"], [UIImage imageNamed: @"123pig0027.png"], [UIImage imageNamed: @"123pig0028.png"], [UIImage imageNamed: @"123pig0029.png"], [UIImage imageNamed: @"123pig0030.png"], [UIImage imageNamed: @"123pig0031.png"], [UIImage imageNamed: @"123pig0032.png"], [UIImage imageNamed: @"123pig0033.png"], [UIImage imageNamed: @"123pig0034.png"], [UIImage imageNamed: @"123pig0035.png"], [UIImage imageNamed: @"123pig0036.png"], [UIImage imageNamed: @"123pig0037.png"], [UIImage imageNamed: @"123pig0038.png"], [UIImage imageNamed: @"123pig0039.png"], [UIImage imageNamed: @"123pig0040.png"], [UIImage imageNamed: @"123pig0041.png"], [UIImage imageNamed: @"123pig0042.png"], [UIImage imageNamed: @"123pig0043.png"], [UIImage imageNamed: @"123pig0044.png"], [UIImage imageNamed: @"123pig0045.png"], [UIImage imageNamed: @"123pig0046.png"], [UIImage imageNamed: @"123pig0047.png"], [UIImage imageNamed: @"123pig0048.png"], nil]; [123pig setAnimationRepeatCount:1]; 123pig.animationDuration =2.7; [123pig startAnimating]; } - (void)tick1{ [self animatePig1]; } - (void) animatePig1{ UIImage *pigImage11=[UIImage imageNamed:@"123pig0048.png"]; if(123pig.image == pigImage11) 123pig.image = pigImage11; else 123pig.image = pigImage11; } - (void)stopTimer { [animationTimer invalidate]; [animationTimer release]; [animationTimer1 invalidate]; [animationTimer1 release]; } -(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [[event allTouches] anyObject]; CGPoint location = [touch locationInView:touch.view]; 123pig.center = location; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; } - (void)dealloc { [super dealloc]; [123pig release]; } @end 

I have an idea that this is the name imageNamed that calls it, and that 2.2.1 does not clear it with a cache even after a memory warning, and on another SO question, someone said: "I understand that the cache + imageNamed: must respect memory warnings on iPhone OS 3.0. Check this out when you get a chance and report bugs if you find that it’s not. " Now, even if I downloaded the firmware and SDK 3.0, I would not know if it clears the imageNamed cache, because I could not test it on the device! By the way, answering, remember that I am new to iPhone sdk. Thanks in advance.

---------------- Edit ---------------- I have just been accepted into the Apple iphone developer program. WOOOHOOO, I will check if 3.0 caches images correctly.

------------- Edit ------------------ Yes, it releases cached images. Check out my answer below for further clarification.

+1
source share
3 answers

Good people. It would seem that iPhone OS 3.0 clears cached images in the memory alert command, wooohooo! Me 1, Xcode 0. A little more detailed: in iPhone os 2.2.1, when you release the animated image view, the cached images will not be released, so if your application downloaded the animation, then, in the end, the iPhone will end its memory and exit. That way, you just need to use other more complex animation methods, and no one wants to do this if they can avoid it. But now liberation clears the cache! I can say that because when I click on a button in my application to liven up the view, there is a little wait until the animation is played, then if it is clicked again there is no wait (because it cached it). But if you press another button that enlivens this view, the previous cached animation will be displayed! Therefore, pressing the first button gives you an initial expectation, so I can relax and continue developing, and then try to fix the memory management problem, which comes down to apple errors.

+1
source

I am really confused about the behavior of your timers. You start the UIImageView pig animation, and then your timer fires 1/3 second later and it sets the pig image to something else?

You might want to combine these two animation methods (UIImageView animation animation and manual animation using a timer). UIImageView is not really designed to play long animations (see this question ). I think it preloads all the images at once when starting the animation - thus, a huge memory gets hit.

The best bet would be to use a timer for everything and save a local variable corresponding to the current frame. When your timer fires, you can only upload one image using imageNamed: and apply it to the UIImageView. I'm not sure what UIImage caching behavior is, but I'm sure 100 of them in UIImageView is a bad idea.

Is there a chance that you can reduce the frame rate of your animation? It seems you are trying to flip all 100 images in a pig animation in 2.7 seconds - that's 37 frames per second! 24 frames per second is likely to be great and help reduce memory footprint.

Also - this is not a topic, but I noticed that you are calling [123pig dealloc] in your dealloc function. In general, you should simply call release, and dealloc will be called automatically if the object's counter remains zero (this means that the object is no longer in use). Manually accessing it can lead to the fact that you destroy things that the object is still using in the application. It probably doesn't matter in this case, but it can cause some unpleasant errors in other scenarios.

Sorry, I don’t have a specific answer to the question about cache. Hope this helps!

0
source

Your dealloc code is incorrect. You should only free 123pig, not free it. You must do this before calling [super dealloc] , because after this call all your instance variables (incling 123pig) can be canceled. Perhaps this was manifested in the fact that it does not free the image memory, since there is a link to 123pig.

0
source

Source: https://habr.com/ru/post/895946/


All Articles