UIView не отвечает при изменении в методе NSTimer
У меня есть этот повторяющийся цикл NSTimer, который проверит, есть ли какие-либо новости в моем приложении. Проверяющая часть не имеет значения и работает нормально, но чтобы показать, есть ли новости или нет, я сделал UIView под названием orangeDot. Это должно быть orangeDot.alpha = 1.0
если есть новости и апельсин orangeDot.alpha = 0.0
если не. Но это не всегда работает. Иногда orangeDot скрыт (альфа =0), когда есть новости, а иногда и наоборот. Это код:
-(void) checkForNews {
NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
bool news = (([defaults boolForKey:@"newsFromChat"]) || ([defaults boolForKey:@"newsFromAwaiting"])) ? YES : NO;
if (news) {
NSLog(@"yay news");
[orangeDot setAlpha:1.0f];
} else {
NSLog(@"nothing new");
[orangeDot setAlpha:0.0f];
}
NSLog(@"%@",orangeDot);
}
NSLog работает отлично, и с этой частью проблем никогда не бывает, но, несмотря на то, что в журнале написано "ура новости", OrangeDot может быть скрыт, и снова наоборот. Но иногда это работает... Я еще не нашел шаблон в ошибке. Я должен отметить, что ни альфа, ни скрытый не работают правильно.
OrangeDot устроился так:
@property (nonatomic, retain) IBOutlet UIView * orangeDot;
и подключен в раскадровке.
Пожалуйста помоги:)
2 ответа
Основываясь на вашем коде, я имею в виду две вещи:
UIView
Обновления должны быть сделаны в главном потоке. Проверьте, вызываете ли вы этот метод из основного потока, или просто вызовите этот метод из основного потока.- (void)checkForNews { dispatch_async(dispatch_get_main_queue(), ^{ NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults]; bool news = (([defaults boolForKey:@"newsFromChat"]) || ([defaults boolForKey:@"newsFromAwaiting"])) ? YES : NO; if (news) { NSLog(@"yay news"); [orangeDot setAlpha:1.0f]; } else { NSLog(@"nothing new"); [orangeDot setAlpha:0.0f]; } NSLog(@"%@",orangeDot); }); }
Ваш
orangeDot
декларация кажется немного подозрительной. Вы объявили какую-то другую переменную с тем же именем? Попробуй позвонитьself.orangeDot
вместо толькоorangeDot
, Обычно XCode не позволяет нам получить доступ к IBOutlet так, как вы это сделали. Если вы объявили это один раз и правильно, вы сможете получить доступ к объекту черезself.orangeDot
или просто_orangeDot
(с начальным подчеркиванием).//using .self [self.orangeDot setAlpha:1.0f]; //or using underline to access the var. without setter [_orangeDot setAlpha:1.0f];
Обновить:
Вы действительно должны сделать цикл, чтобы проверить наличие обновлений по умолчанию для вашего пользователя? Как насчет того, чтобы забыть об этом таймере и реализовать шаблон NSNotification (или делегаты, или что-то еще)? Вам просто нужно отправить событие уведомления и прослушать его на контроллере относительного представления: я ожидаю, что вы уже знаете, как его реализовать, но я оставлю здесь небольшой пример:
//Somewhere ... just after you update your news data.
[[NSNotificationCenter defaultCenter] postNotificationName:@"NewChatDataAvailable" object:nil];
На этом этапе вы сообщаете всему приложению, что у вас есть новые данные чата, без необходимости проверять их в цикле. Теперь все, что нам нужно сделать, это зарегистрироваться, чтобы получать эти уведомления:
//In this example I will register on viewDidLoad:
- (void)viewDidLoad:(BOOL)animated {
[super viewDidLoad:animated];
//Now, your method will be called on when necessary (when data arrives)
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(checkForNews)
name:@"NewChatDataAvailable"
object:nil];
}
Теперь давайте немного улучшим ваш код:
- (void)checkForNews {
dispatch_async(dispatch_get_main_queue(), ^{
NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
//You don't need to put the ? YES : NO stuff, and BOOL in capital letters
BOOL hasNews = (([defaults boolForKey:@"newsFromChat"]) ||
([defaults boolForKey:@"newsFromAwaiting"]));
if (hasNews) {
NSLog(@"yay news");
[self.orangeDot setAlpha:1.0f];
} else {
NSLog(@"nothing new");
[self.orangeDot setAlpha:0.0f];
}
NSLog(@"%@",self.orangeDot);
});
}
Я надеюсь, что это поможет вам. И... когда вы обновляете свой вопрос кодом или чем-то другим, редактируйте свой вопрос и вставляйте туда код, не публикуйте его как ответ.
Спасибо за помощь!
Лучший обзор кода:
...
@synthesize orangeDot;
...
- (void) viewDidLoad {
...
[self reloader];
...
}
- (void) reloader{
if (refreshAuto == nil) {
refreshAuto = [NSTimer scheduledTimerWithTimeInterval: 2.0
target: self selector:@selector(checkForNews) userInfo: nil repeats:YES];
}
}
- (void)checkForNews {
dispatch_async(dispatch_get_main_queue(), ^{
NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
bool news = (([defaults boolForKey:@"newsFromChat"]) || ([defaults boolForKey:@"newsFromAwaiting"])) ? YES : NO;
if (news) {
NSLog(@"yay news");
[orangeDot setAlpha:1.0f];
} else {
NSLog(@"nothing new");
[orangeDot setAlpha:0.0f];
}
NSLog(@"%@",orangeDot);
});
}
Журнал будет иногда выглядеть так, когда отображается OrangeDot:
...
2015-05-25 12:02:23.788 Teazr[1314:442396] nothing new
2015-05-25 12:02:23.789 Teazr[1314:442396] <UIButton: 0x154520f40; frame = (322 47; 11 11); alpha = 0; opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x17422a740>>
...
@ Synthesizing является личным предпочтением и не требуется. Но это работает так же с self.orangeDot и без синтеза.