Objective-C: 每秒调用方法的最佳实践

Objective-C: Best practice to call method every second

场景 我需要一种每秒触发的方法。我还需要能够随时停止该方法的触发。目前我正在使用 NSTimer:

代码

self.controlTimer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updatePlayer) userInfo:nil repeats:YES];

问题 我确定我可以使用 NSTimer 实现此功能,并在我希望它停止时调用 invalidate,但我很担心关于在 UITableViewCell 中放置 NSTimer 的性能开销。

问题有谁知道每秒调用一个方法的更轻量级替代方法?

NSTimer 非常轻量级。您只需要确保在重复使用单元格时正确处理单元格的计时器即可。

我已经在 UITableViewCellUICollectionViewCell 自定义子类中使用了 NSTimer 个实例来完成您正在做的事情,但我创建了一个协议 PLMMonitor 来提供 -startMonitoring-stopMonitoring 在我的单元格上与 start/stop (参见:invalidate)任何计时机制的合同。

协议

(显然协议名称前缀可以很容易地改变)

@protocol PLMMonitor <NSObject>

@required

- (void)startMonitoring;
- (void)stopMonitoring;

@end

使用单元格可见性来控制计时器

然后我可以利用 -[UITableViewDataSource tableView:cellForRowAtIndexPath:] or -[UICollectionViewDelegate collectionView:willDisplayCell:forItemAtIndexPath:] 在符合协议的单元格上调用 -startMonitoring(允许 UITableView/UICollectionView 中的混合单元格):

- (void)collectionView:(UICollectionView *)collectionView willDisplayCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath
{
    if ([cell conformsToProtocol:@protocol(PLMMonitor)])
    {
        [(UICollectionViewCell<PLMMonitor> *)cell startMonitoring];
    }
}

然后我使用 -[UITableViewDelegate tableView:didEndDisplayingCell:forRowAtIndexPath:] or -[UICollectionViewDelegate collectionView:didEndDisplayingCell:forItemAtIndexPath:] 在符合协议的单元格上调用 -stopMonitoring(再次允许 UITableView/UICollectionView 中的混合单元格):

- (void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath
{
    if ([cell conformsToProtocol:@protocol(PLMMonitor)])
    {
        [(UICollectionViewCell<PLMMonitor> *)cell stopMonitoring];
    }
}

使用视图控制器可见性来控制计时器

您还应该将代码添加到 -viewWillAppear-viewWillDisappear-startMonitoring-stopMonitoringvisible 单元格符合到协议以确保计时器在不再可见时得到适当的started/stopped:

- (void)viewWillAppear
{
    for (UICollectionViewCell *aCell in [self.collectionView visibleCells])
    {
        if ([aCell conformsToProtocol:@protocol(PLMMonitor)])
        {
            [(UICollectionViewCell<PLMMonitor> *)aCell startMonitoring];
        }
    }
}

- (void)viewWillDisappear
{
    for (UICollectionViewCell *aCell in [self.collectionView visibleCells])
    {
        if ([aCell conformsToProtocol:@protocol(PLMMonitor)])
        {
            [(UICollectionViewCell<PLMMonitor> *)aCell stopMonitoring];
        }
    }
}

NSTimers 的性能影响/能源使用

可以减少 NSTimer 实例对电池寿命等影响的一种方法是利用它们的 tolerance 属性,它允许 iOS 执行 some power savings magic with them while sacrificing a strict firing interval.

替代Timer/Trigger机制