iOS - Objective-C - 小部件文本和图像加倍 - 旧数据未清除

标签 ios widget

在 iOS 应用程序小部件中,我只能在某些设备上看到双倍数据(见下图)。我试图识别设备、iOS 版本,但它似乎是“随机的”。另外,我无法自己调试它,因为在我的每台设备上,所有内容都正确呈现并且进行盲调试不起作用(AppStore 上的几次更新但仍然出现相同的错误)。

在小部件中,我(在后台线程中)从网络下载新数据并将它们(在 dispatch_get_main_queue() 中)放入标签、图像等中。一切正常,但有时旧数据未清除”。在我的小部件设计文件中,我已经清除了所有“默认”文本,所以这不是这个问题。

enter image description here

双图标和文本 4.1°C 和 7.9°C 重叠

我的小部件代码的主要部分是(通过删除其他标签、表格和地理位置缩短):

- (void)viewDidLoad
{
    [super viewDidLoad];
    if ([self.extensionContext respondsToSelector:@selector(widgetLargestAvailableDisplayMode)])
    {
        //this is iOS >= 10                
        self.extensionContext.widgetLargestAvailableDisplayMode = NCWidgetDisplayModeExpanded;
    }


    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(FinishDownload:) name:@"FinishDownload" object:nil];


    self.preferredContentSize = CGSizeMake(320, 160);

     [self updateData];
}

-(void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    [self updateData];
}

-(void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    [self updateData];
}

-(void)updateData
{

    [[[DataManager SharedManager] settings] Reload];


    [[CoreDataManager SharedManager] reset];

    if ([[DataManager SharedManager] DownloadDataWithAfterSelector:@"FinishDownload"] == NO)
        {
            //no need to download update - refill data now
            //if downloading - wait for download
            [self FillData];
        }
    }


}


-(void)FinishDownload:(NSNotification *)notification
{
    dispatch_async(dispatch_get_main_queue(), ^{
        [self FillData];
    });

}

-(void)FillData
{
    //a lot of code - example of setting temperature
    NSString *str = [NSString stringWithFormat:@"%@ °C", act.temp_act];
    self.lblTemp.text = str;
    [self.lblTemp sizeToFit];


    if (self.completionHandler != nil)
    {
        self.completionHandler(NCUpdateResultNewData);
    }
}



- (void)widgetPerformUpdateWithCompletionHandler:(void (^)(NCUpdateResult))completionHandler
{
    // Perform any setup necessary in order to update the view.

    // If an error is encountered, use NCUpdateResultFailed
    // If there's no update required, use NCUpdateResultNoData
    // If there's an update, use NCUpdateResultNewData

    //completionHandler(NCUpdateResultNewData);
    NSLog(@"=== widgetPerformUpdateWithCompletionHandler === ");

    self.completionHandler = completionHandler;

    [self updateData];


}

- (UIEdgeInsets)widgetMarginInsetsForProposedMarginInsets:(UIEdgeInsets)defaultMarginInsets
{
    return UIEdgeInsetsMake(0, 0, 5, 5);
}


- (void)widgetActiveDisplayModeDidChange:(NCWidgetDisplayMode)activeDisplayMode withMaximumSize:(CGSize)maxSize
{
    if (activeDisplayMode == NCWidgetDisplayModeExpanded)
    {
        self.preferredContentSize = CGSizeMake(320, 160);            
    }
    else if (activeDisplayMode == NCWidgetDisplayModeCompact)
    {
        self.preferredContentSize = maxSize;            
    }
}

最佳答案

  1. 查看生命周期

    不要重复viewDidLoadviewWillAppear/viewDidAppear中的工作。
    加载的 View 将命中所有三个 方法。将 viewDidLoad 用于在 UIViewController 的生命周期内必须恰好执行一次的操作。
    潜在问题:
    触发对 [self updateData] 的 3 次调用,可能相互冲突,可能与竞争的 NCUpdateResult 完成处理程序3

    /li>
  2. 平衡观察者

    看来 addObserver 从未被 removeObserver 平衡。这些注册方法的一个很好的位置是一组平衡的消息,例如 view___Appearview___Disappear 方法,如 StackOverflow answer 中所述。 .
    潜在问题:
    持久注册可能超出范围的对象的通知。

  3. 不缓存操作系统处理程序

    可能滥用 NCUpdateResultNewData 完成处理程序:NCUpdateResult 被传递给 widgetPerformUpdateWithCompletionHandler 以用于该特定调用,而不是存储以供多次重用.它可能应该作为参数传递给 updateData 而不是存储在全局中,然后传递给 FillData,并最终在一次性使用。

    if (nil != self.completionHandler) {
        self.completionHandler(NCUpdateResultNewData);
        self.completionHandler = nil; // One time use
    }
    

    widgetPerformUpdateWithCompletionHandler 的每次调用都有自己的周期,如 this StackOverflow answer 中所述。 .

  4. 布局和自动布局

    请注意,iOS 正在制作您的小部件的快照;在 Interface Builder 中,确保使用正确的 View 分层。特别注意透明度和绘图标志。利用自动布局调整对象大小/调整大小/对齐对象

关于iOS - Objective-C - 小部件文本和图像加倍 - 旧数据未清除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40471989/

相关文章:

ios - 使用不同的数据呈现当前 View Controller

ios - firebaseobserveSingleEvent 在 swift 中已弃用

ios - 在 OS X 上使用 ndenv 设置 React Native

widget - 在静态调用的方法中使用小部件

Android - 无法打开内容 : file:///storage/emulated/0

widget - CKEditor,如何删除小部件之前和之间的空段落

ios - Xcode 7 上的 Gmail API 快速入门说明不起作用

iphone - Tabbar 应用程序中的 PopViewController

python - Tkinter Canvas 将项目移动到顶层

javascript - Gmail 的 Chrome 扩展程序