代码之家  ›  专栏  ›  技术社区  ›  squeezemylime

为什么在NSNotificationCenter更新后,我的UILabels不刷新新信息?

  •  1
  • squeezemylime  · 技术社区  · 15 年前

    我正在开发一个天气应用程序,一切正常 完美 …除了显示数据的UILabels。一旦应用程序第一次加载,它就会遍历并正确地找到数据,然后显示它。

    在我的主RootViewController中,这是其中一个uilabel的外观:

    UILabel *myCityLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 30, 200, 80)];
    [myCityLabel setText:[NSString stringWithFormat:@"%@",placemark.locality]];
    myCityLabel.textAlignment = UITextAlignmentLeft;
    myCityLabel.textColor = [UIColor blackColor];
    myCityLabel.font = [UIFont fontWithName:@"Helvetica" size:24];
    myCityLabel.backgroundColor = [UIColor clearColor];
    [self.view addSubview:myCityLabel];
    [myCityLabel release];
    

    我在后台运行核心定位。在我的appDelegate中,我看到这两个方法在再次调用应用程序时(在关闭它之后)被调用:

    - (void)applicationDidBecomeActive:(UIApplication *)application {
    NSLog(@"applicationDidBecomeActive:");
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceNotificationReceived:) name:UIApplicationDidBecomeActiveNotification object:nil];
    
    /*
     Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
     */
    
    lbsViewController = [[LBSViewController alloc] init];
    [lbsViewController viewDidLoad];
    }
    
    - (void)deviceNotificationReceived:(NSNotification *)notification
    {
        NSLog(@"was this received?");
    }
    

    我要做的是启动 视图加载 lbsViewController(我的主RootViewController)的方法。我可以通过控制台看到它返回了新信息,甚至调用了viewDidLoad函数,但是标签没有用新数据刷新…有什么建议可以用什么路由来解决这个问题?

    我应该注意到,UILabels使用新数据刷新的唯一时间是在将应用程序从Xcode构建到我的设备上。

    2 回复  |  直到 15 年前
        1
  •  2
  •   Community Mohan Dere    9 年前

    你说你通过删除多任务来解决问题。您的问题是从后台线程发送的NSNotification到达了同一个后台线程,并且您试图从该后台线程更新UILabel。这是不允许的-您必须从主线程更新UI元素。

    要解决此问题,可以使用以下命令对主线程执行marshall调用:

    - (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait
    

    所以,类似这样(在通知处理程序中):

    [viewController.outputLabel performSelectorOnMainThread: @selector( setText: ) withObject: currentChar waitUntilDone: YES];
    

    注意,这和我对这个问题的回答是一样的: How do I display characters to a UILabel as I loop through them?

        2
  •  0
  •   Tommy    15 年前

    两行:

    lbsViewController = [[LBSViewController alloc] init];
    [lbsViewController viewDidLoad];
    

    正在分配一个全新的LBSViewController并对其调用viewDidLoad。可能你想在现有的LBSVIEW控制器对象上调用VIEWDIDEAD,而不是分配新的对象(即,删除这两行中的第一行)。

    无论如何,最好让视图控制器观察通知本身并在内部处理所有事情。这类重载viewDidLoad的含义,并且添加一个具有替代名称的方法可能会以一种奇怪的方式分发逻辑。