在 NSTimer 方法中更改时 UIView 没有响应
UIView is not responding when changed in NSTimer method
我有这个 NSTimer 重复循环,它会检查我的应用程序中是否有任何新闻。检查部分是无关紧要的,它工作正常,但为了显示是否有新闻,我制作了一个名为 orangeDot 的 UIView。如果有新闻,这应该是 orangeDot.alpha = 1.0
,如果没有,则应该是 orangeDot orangeDot.alpha = 0.0
。但它并不总是有效。有时,当有新闻时,orangeDot 会隐藏 (alpha=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 工作完美,这部分从来没有问题,但即使日志显示 "yay news" orangeDot 也可能被隐藏,反之亦然。但有时它会起作用......我还没有在错误中找到模式。
我不得不提到 .alpha 和 .hidden 都不能正常工作。
orangeDot 是这样坐起来的:
@property (nonatomic, retain) IBOutlet UIView * orangeDot;
并在故事板中连接。
请帮忙:)
根据您的代码,我有两点想法:
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);
});
}
希望对你有所帮助。而且......当你用代码或其他东西更新你的问题时,编辑你的问题并在那里插入代码,不要post它作为答案。
感谢您到目前为止的帮助!
更好地概述代码:
...
@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 相同,没有合成..
我有这个 NSTimer 重复循环,它会检查我的应用程序中是否有任何新闻。检查部分是无关紧要的,它工作正常,但为了显示是否有新闻,我制作了一个名为 orangeDot 的 UIView。如果有新闻,这应该是 orangeDot.alpha = 1.0
,如果没有,则应该是 orangeDot orangeDot.alpha = 0.0
。但它并不总是有效。有时,当有新闻时,orangeDot 会隐藏 (alpha=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 工作完美,这部分从来没有问题,但即使日志显示 "yay news" orangeDot 也可能被隐藏,反之亦然。但有时它会起作用......我还没有在错误中找到模式。 我不得不提到 .alpha 和 .hidden 都不能正常工作。
orangeDot 是这样坐起来的:
@property (nonatomic, retain) IBOutlet UIView * orangeDot;
并在故事板中连接。
请帮忙:)
根据您的代码,我有两点想法:
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);
});
}
希望对你有所帮助。而且......当你用代码或其他东西更新你的问题时,编辑你的问题并在那里插入代码,不要post它作为答案。
感谢您到目前为止的帮助!
更好地概述代码:
...
@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 相同,没有合成..