在NSTimer方法中更改时,UIView没有响应

时间:2015-05-25 09:23:20

标签: objective-c xcode uiview alpha iboutlet

我有这个NSTimer重复循环,它将检查我的应用程序中是否有任何新闻。检查部分是不相关的,它工作正常,但为了显示是否有新闻,我做了一个名为orangeDot的UIView。如果有新闻,则应为orangeDot.alpha = 1.0,否则为{0} orangeDot.alpha = 0.0。但它并不总是奏效。有时橙色点在有新闻时隐藏(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”,橙色点也可能被隐藏,反之亦然。但有时候它有效...我还没有在bug中找到一个模式。 我不得不提到.alpha和.hidden都不对。

橘子点像这样坐着:

@property (nonatomic, retain) IBOutlet UIView * orangeDot;

并在故事板中连接。

请帮助:)

2 个答案:

答案 0 :(得分:1)

根据您的代码,我有两点需要注意:

  1. 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);
        });
    }
    
  2. 您的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];
    
  3. <强>更新

    您真的需要循环检查用户默认值的更新吗?如何忘记这个计时器的东西并实现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);
        });
    }
    

    我希望它可以帮到你。并且...当您使用代码或其他内容更新您的问题时,请编辑您的问题并在其中插入代码,不要将其作为答案发布。

答案 1 :(得分:0)

感谢您的帮助!

更好地了解代码:

...
@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的工作方式相同,没有合成..