Objective-C: перерисовка объектов на экране - PullRequest
2 голосов
/ 22 ноября 2011

У меня есть файл GameScreen.m (это упрощенный фрагмент кода):

- (IBAction) onCellClick:(id) sender
{
  points +=1;
  self.myScore.text = [[NSNumber numberWithInt: points] stringValue]; 
 //myScore is a label in GameScreenViewController xib
} 

То есть, если щелкнуть ячейку в представлении, текстовая метка увеличится на 1. Пока все хорошо.

тогда, в том же коде, у меня есть таймер:

- (void) startTimer
{ 
    [NSTimer scheduledTimerWithTimeInterval:1.0f
                                     target:self
                                   selector:@selector(updateCounter:)
                                   userInfo:nil
                                    repeats:YES];
}

его метод updateCounter:

- (void) updateCounter:(NSTimer *)theTimer
{
     int seconds;
     static int count = 0;
     count +=1;
     timeElapsed = [[NSString alloc] initWithFormat:@"%d", seconds + count];
     self.time.text = timeElapsed;
     //time is a label in GameScreenViewController xib
}

дело в том, что метка "time" в этом случае не обновляется (каждый раз по 1 секунде). Я вставил AlertView, чтобы проверить, является ли метод startTimer правильным и правильно вызванным, и это действительно так (он показывает раздражающее представление предупреждений каждую секунду со значением timeElapsed). Тем не менее, я могу получить значение метки времени, которое будет изменено.

Почему моя метка очков обновляется после действия, а метка времени не обновляется каждую секунду? Можно ли как-нибудь обновить его, не включая мой код в ViewController?

// примечание: моя кодировка разбита на три файла: appDelegate переворачивает экраны и отправляет значения между ними; мои viewControllers - только окна и, наконец, мой класс GameScreen управляет всеми процессами. Из xib владелец файла подключается к ViewController, а представление подключается к классу GameScreen.

Большое спасибо за любые отзывы, пожалуйста, не стесняйтесь спрашивать о любом необходимом дополнительном коде.

Ответы [ 2 ]

0 голосов
/ 24 ноября 2011

Я прошел через Гадкий обход. Это работает в некоторой степени, но я прошел через такое дерьмовое исправление, что я слишком смущен, чтобы делиться ...

По сути, я переместил свой таймер непосредственно в ViewController, так как я хочу, чтобы он срабатывал при загрузке просмотра и не мог заставить его работать с вызовом из ViewController - (void) viewDidLoad в GameScreen - (void) startTimer. Все остальные вещи, включающие оба метода, в значительной степени дублированы (хорошо, не дублированы, скажем, «полиморфизированы», так как я обрабатываю некоторые переменные для их запуска).

Похоже, что мои IBActions GameScreen.m могут запускать только другие методы внутри моего GameScreen.m, но не на GameScreenViewController.m. Таким образом, я обрабатываю поведение своих кнопок на GameScreen.m, а на GameScreenViewController.m я просто обрабатываю «автоматические» вещи; то есть все, что не зависит от взаимодействия с пользователем. Это заставило меня дублировать некоторые IBOutlets в зависимости от необходимого ввода / вывода, поэтому я предполагаю, что, поскольку он теперь работает, вы не сможете заметить разницу, если не уйдете из-под капота ...

Спасибо всем за отзывы.

0 голосов
/ 22 ноября 2011

Это необходимо сделать (операции, связанные с пользовательским интерфейсом) в главном потоке.

Вместо строки

 self.time.text = timeElapsed;

выполните следующие действия:

[self.time performSelectorOnMainThread:@selector(setText:) withObject:timeElapsed waitUntilDone:NO];

Редактировать:

- (void) updateCounter:(NSTimer *)theTimer
{
     //int seconds;
     static int count = 0;
     count +=1;
     NSString *timeElapsed1 = [[NSString alloc] initWithFormat:@"%d", count];
    [self.time performSelectorOnMainThread:@selector(setText:) withObject:timeElapsed1 waitUntilDone:NO];
    [timeElapsed1 release];
     //time is a label in GameScreenViewController xib
}
...