2009-06-20 40 views
1

我正在为iPhone创建一个应用程序,其中涉及具有多个动画相同的UIImageView的所有动画的按钮。它在模拟器中运行良好(几乎所有的应用程序都可以),但是当它涉及到设备时,它会很好地播放动画,但通过重复按下按钮,应用程序就会退出。到目前为止,我实现了2个按钮。这是按下按钮时发生的情况。 好吧,当我的应用程序启动时,我有44 MB的ram可用,然后当我按下开始动画的2个按钮中的第一个时,可用内存下降到31,然后爬到32,然后当我按下第二个按钮时记忆下降到9,然后爬到24,然后奇怪地下降到10。如果按下第一个按钮,则可用内存将攀升至14MB。在重复按下这些按钮时,应用程序内存将降至4至3 MB并退出。仪器中没有泄漏。这里是我的代码,任何人都可以发现我的记忆问题潜伏在哪里。 (顺便说一句,我仍在2.2.1上开发,因为如果我升级到3.0,我将无法在设备上测试我的应用程序,因为我没有注册苹果开发人员计划,并且我遵循在线教程获取应用到,只有与2.2.1工程设备)iPhone SDK:3.0是否清除imageNamed的缓存?因为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 

我有一个想法,它的imageNamed这就是导致它和2.2.1不清晰甚至内存警告后的缓存,并在另一个SO问别人说:“我的理解是,+ imageNamed:cache应该尊重iPhone OS 3.0上的内存警告,如果发现情况并非如此,请在有机会时进行测试并报告错误。现在,即使我下载了3.0的固件和SDK,我也不知道它是否清除了imageNamed的缓存,因为我无法在设备上进行测试!顺便提一下,请记住我是iPhone sdk的新手。提前致谢。

----------------编辑---------------- 我刚刚被接纳进苹果iphone开发者计划。 WOOOHOOO,我会检查3.0是否正确释放缓存的图像。

-------------编辑------------------ 是的,它释放缓存的图像。请查看下面的答案以作进一步澄清。

回答

1

好的人,看起来iPhone OS 3.0确实清除了接收内存警告命令缓存的图像,wooohooo!我1,Xcode 0.更详细一点:在iPhone OS 2.2.1中,当您释放动画图像视图时,缓存的图像不会被释放,所以如果您的应用程序有大量动画,那么最终iPhone会用完记忆和退出。所以你只需要进入其他更复杂的动画方法,没有人愿意这样做,如果他们可以避免它。但现在释放确实清除缓存!我可以说,因为当我按下应用程序中的按钮来为视图设置动画时,有一段时间才会播放动画,如果再次按下该按钮则不会等待(因为它将其缓存)但如果按另一个按钮动画的视图,以前的缓存动画被释放!所以按下第一个按钮会给你原来的等待时间,所以我现在可以放松一下,继续开发,而不是试图修复一个归结为苹果故障的内存管理问题。

+0

您的取消分配代码不正确,可能有不释放UIImageView的副作用。 – Jason 2009-06-21 15:29:26

0

我真的很困惑你的计时器的行为。你开始猪的UIImageView动画,然后在1/30秒后,你的计时器会触发,并将猪图像设置为其他内容?

您可能想整合这两种动画方法(UIImageView animationImages和使用计时器的手动动画)。 UIImageView实际上并不是要播放长动画(请参阅this question)。我认为它在您开始动画时一次预先加载所有图像 - 因此会产生巨大的记忆力。

更好的选择可能是对所有东西都使用定时器,并保留与当前帧对应的局部变量。当您的计时器触发时,您可以使用imageNamed加载一个图像:并将其应用于UIImageView。我不确定UIImage的缓存行为是什么,但我非常确定将它们中的100个堆放到UIImageView中是一个坏主意。

有没有机会降低动画的帧率?看起来你正试图在2.7秒内翻动猪动画中的所有100幅图像 - 这就是37 fps! 24 fps可能会很好,有助于降低内存占用。

另外 - 这是脱离主题,但我注意到你在你的dealloc函数中调用[123pig dealloc]。一般来说,你应该调用release,如果对象的保留计数为零(意味着对象不再使用),dealloc将自动调用。手动调用它可能会导致您摧毁应用程序中另一个对象仍在使用的内容。在这种情况下可能无关紧要,但在其他情况下可能会导致一些令人讨厌的错误。

对不起,我对缓存问题没有确切的答案。希望那有所帮助!

+0

好的,感谢您提供有用的建议,但仅仅是为了澄清,注释掉的代码是没有意义的,实际上我只是为您在那里看到的框架设置了动画。这是我原来的计划,动画100个图像,现在我不是,顺便说一句,定时器用于设置动画的最后一帧是图像视图的图像。它似乎工作。 – Amanda 2009-06-20 20:44:59

0

您的dealloc代码不正确。你只应该释放123pig,而不是释放它。你应该在调用[super dealloc]之前这样做,因为在调用之后,所有的实例变量(incling 123pig)都可能失效。这可能表现为不释放图像内存,因为有一个对123pig的悬挂引用。

+0

是的,我被另一位成员告知,我相应地编辑了我的代码,结果并不是问题所在。它是imageNamed,即使在内存警告后,也不会释放它的缓存图像,这是造成问题的原因。 – Amanda 2009-06-21 17:10:28