从类更新所有扩展视图会导致延迟?

Posted

技术标签:

【中文标题】从类更新所有扩展视图会导致延迟?【英文标题】:Updating all extended views from class gives delay? 【发布时间】:2013-11-18 12:52:56 【问题描述】:

我有最奇怪的事情,我有一个 uinavigationgroup,所有页面都继承自 custenViewController,控制器在右上角添加了一个按钮,其中带有一个带有迭代器的红色徽章。该应用程序可以有无限的页面,因此所有页面都从这里扩展。所以我可以一次更改所有页面的迭代器,每个页面的 setBadge 函数。

#import "CustomView.h"


@interface CustomView ()
@end

@implementation CustomView

- (void)viewDidLoad

    [super viewDidLoad];

    // add notification icon
    UIBarButtonItem *rightButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"icn_notification.png"]
                                                                    style:UIBarButtonItemStylePlain
                                                                   target:self
                                                                   action:@selector(openNotifications:)];
    self.navigationItem.rightBarButtonItem = rightButton;

    // add the badge and set it hidden
    badge = [[UILabel alloc] init];
    badge.frame = CGRectMake(270, -45, ( ( 1 * 8 ) + 14), 22);
    badge.hidden = false;
    badge.text = @"?";
    badge.textColor = [UIColor whiteColor];
    badge.backgroundColor = [UIColor redColor];
    badge.layer.cornerRadius = 11;
    badge.textAlignment = NSTextAlignmentCenter;
    badge.font = [UIFont systemFontOfSize:16];
    badge.shadowColor = [UIColor clearColor];
    badge.shadowOffset = CGSizeMake(0,0);

    self.navigationController.navigationBar.layer.zPosition = -1;
    [self.view addSubview:badge];

    // set the count to the badge
    appDelegate = [[UIApplication sharedApplication] delegate];
    [appDelegate.myData addCustomView:self];
    [self setBadge: appDelegate.myData.badgeCount];


-(void)setBadge: (int)count
    // set the number
    NSString *text = [[NSString alloc] initWithFormat:@"%d", count];
   [badge setText:text];
   [badge setFrame:CGRectMake(270, -45, ( ( [text length] * 8 ) + 14), 22)];
   [badge setHidden: (count == 0)];


-(void)openNotifications: (id)sender

    // open the subview
    [self.navigationController pushViewController:appDelegate.notificationView animated:YES];


@end

当我要更新所有徽章时,我会这样做:

// update badges
for (CustomView *view in customViews) 
    [view setBadge: self.badgeCount];

这确实有效,只是最奇怪的是没有立即执行,有时会延迟 1 分钟,当我在应用程序中更改页面时,它看起来速度更快,但我真的不明白延迟!

请有人帮忙!这花费的时间太长了!

谢谢!!

好的,感谢 David H,我在主线程上执行它,只有当我不在主线程时会发生什么?代码没有被执行,那我该怎么办?

// UI stuff make sure im on the Main Thread
if( [NSThread isMainThread] )
    // update badges
    for (CustomView *view in customViews) 
        [view setBadge: self.badgeCount];
    
    // refresh table
    [self.nTable reloadData];
    [self.mTable reloadData];
else
    NSLog(@"NOT ON MAIN!!!! %d", [NSThread isMainThread]);

这行得通,只是这个创建是我的代码没有执行的理论情况.....现在我不知所措

【问题讨论】:

确保您在主线程上执行此操作!任何其他地方都可能导致这种奇怪的行为! David H,感谢您的评论,您究竟是什么意思?主线程? 在你的“for循环”中,在它开始之前,确保你在主线程上:assert([NSThread isMainThread]);,如果不是各种奇怪的事情都会发生。我在我的代码中使用这些断言来确保 UI 活动永远不会在任何其他线程上发生。这些问题可能需要数周时间才能找到,但如果您使用大量块和调度队列(就像我一样),通常会突然出现。 大卫 H,救命稻草!这就像一个魅力,只有当你不在主要头上时才会发生,它不会被执行...... 【参考方案1】:

在你的“for 循环”中,在它开始之前,确保你在主线程上:assert([NSThread isMainThread]);,如果不是各种奇怪的事情都会发生。我在我的代码中使用这些断言来确保 UI 活动永远不会在任何其他线程上发生。这些问题可能需要数周时间才能找到,但如果您使用大量块和调度队列(就像我一样),通常会突然出现。

要处理在其他线程上接收这个,只需将整个事情包装在一个分派块中并将其分派到主线程。你真的不需要检查你是怎么得到它的,因为它在主线程上,所以代码总是可以工作的。

【讨论】:

以上是关于从类更新所有扩展视图会导致延迟?的主要内容,如果未能解决你的问题,请参考以下文章

(太多)导致问题的视图

RxCocoa - 当有延迟时防止多个视图控制器推送

从目标视图更新 SwiftUI 列表数据会导致意外行为

使用导致崩溃的搜索结果更新表视图

setNeedsDisplayInRect:导致整个视图被更新

每次单击大纲视图行时,如何更新行值和子项