2014-11-04 4 views
1

Я обнаружил проблему с моим образцовым проектом. Я просто создаю schedTimer, который «анимирует» метку, а затем, когда я достиг результата, который я хочу, я аннулирую таймер, и я установил другой, на этот раз как «часы». Это код, я используюПостоянное выделение памяти кучи NSTimer

// 
// ViewController.m 
// 
// 
// 
// 
// 

#import "ViewController.h" 

#define ANIMATION_INTERVAL    0.07 // in secondi 
#define ANIMATION_DURATION    1 // in secondi 

@interface ViewController() 
{ 
    int contatore; 
    NSString *hour; 
    NSString *minute; 
    NSString *second; 
} 

@end 

@implementation ViewController 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view, typically from a nib. 

    contatore = 0; 

    [self startTimeAnimation]; 


} 

- (void)didReceiveMemoryWarning { 
    [super didReceiveMemoryWarning]; 
    // Dispose of any resources that can be recreated. 
} 


-(void)startTimeAnimation 
{ 
    NSTimer * animationTimer = [NSTimer scheduledTimerWithTimeInterval:ANIMATION_INTERVAL target:self selector:@selector(timeout:) userInfo:nil repeats:YES]; 
} 

-(void)timeout: (NSTimer *)timer 
{ 
    // Simulate of the Timer Duration with a counter 
    if (contatore < ceilf(ANIMATION_DURATION/ANIMATION_INTERVAL)) 
    { 
     // Proceed with animation 
     contatore++; 

     int tempHour = arc4random_uniform(24); 
     int tempMinute = arc4random_uniform(60); 
     int tempSecond = arc4random_uniform(60); 

     if (tempHour < 10) 
     { 
      hour = [NSString stringWithFormat:@"0%d", tempHour]; 
     } 
     else 
     { 
      hour = [NSString stringWithFormat:@"%d", tempHour]; 
     } 

     if (tempMinute < 10) 
     { 
      minute = [NSString stringWithFormat:@"0%d", tempMinute]; 
     } 
     else 
     { 
      minute = [NSString stringWithFormat:@"%d", tempMinute]; 
     } 

     if (tempSecond < 10) 
     { 
      second = [NSString stringWithFormat:@"0%d", tempSecond]; 
     } 
     else 
     { 
      second = [NSString stringWithFormat:@"%d", tempSecond]; 
     } 

     _orarioLbl.text = [NSString stringWithFormat:@"%@:%@:%@", hour, minute, second]; 
    } 
    else 
    { 
     // Stops animation 
     [timer invalidate]; 
     [timer release]; 
     contatore = 0; 



     [self setActualTime]; 


     // Starts clock 
     NSTimer *clockTimer = [NSTimer timerWithTimeInterval:.5f target:self selector:@selector(updateClock) userInfo:nil repeats:YES]; 
     [[NSRunLoop mainRunLoop] addTimer:clockTimer forMode:NSRunLoopCommonModes]; 
    } 
} 

-(void)updateClock 
{ 
    [self setActualTime]; 
} 


-(void)setActualTime 
{ 
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 

    [dateFormatter setDateFormat:@"HH"]; 
    hour = [dateFormatter stringFromDate:[NSDate date]]; 

    [dateFormatter setDateFormat:@"mm"]; 
    minute = [dateFormatter stringFromDate:[NSDate date]]; 

    [dateFormatter setDateFormat:@"ss"]; 
    second = [dateFormatter stringFromDate:[NSDate date]]; 

    _orarioLbl.text = [NSString stringWithFormat:@"%@:%@:%@", hour, minute, second]; 
    [dateFormatter release]; 
} 

@end 

Поскольку я начинаю «часы», память по-прежнему остается на 19/20 МБ с постоянным постоянным распределением. Когда таймер обновляет значение минут, постоянные распределения увеличиваются, как вы можете видеть в gif! Как это возможно? Однако, 19 Мб памяти слишком много для простых часов, не так ли? Профилирование на инструментах, новые распределения - все о CoreGraphics!

animated gif Instruments

РЕДАКТИРОВАТЬ Я проверил его на другом устройстве и постоянные распределения уменьшается. Я не знаю почему, но я решил таким образом. Спасибо

ответ

2

NSTimer сохраняет свою цель и может привести к циклу удержания. Захватите слабую ссылку на self и установить, что в качестве цели:

__weak typeof(self) weakSelf = self; 
NSTimer * animationTimer = [NSTimer scheduledTimerWithTimeInterval:ANIMATION_INTERVAL target:weakSelf selector:@selector(timeout:) userInfo:nil repeats:YES]; 

и

__weak typeof(self) weakSelf = self; 
NSTimer *clockTimer = [NSTimer timerWithTimeInterval:.5f target:weakSelf selector:@selector(updateClock) userInfo:nil repeats:YES]; 

Могу ли я также рекомендую вам создать свойство для dateFormatter как NSDateFormatter s дорого создать. И почему вы выпускаете dateFormatter? Вы не используете ARC?

+0

Нет, я не использую ARC, потому что мне пришлось реализовать этот образец в самом большом проекте, который он еще не преобразовал в ARC. EDIT: с этими изменениями скачок в выделениях памяти больше, чем раньше. от 50/60 ассигнований - до 1600! –

 Смежные вопросы

  • Нет связанных вопросов^_^