从2.1升级到2.2后,WCSession sendmessage速度变慢了一倍。

3

我所从事的iOS应用程序配有一个Apple Watch应用程序。最近我们收到了一些关于GPS距离更新变慢的投诉,手表比手机慢几秒钟。我已经开始调查并编写了一些测试代码,来自[[WCSession defaultSession] sendMessage:message replyHandler:replyHandler errorHandler:errorHandler的回复块在watchOS 2.2与2.1相比明显慢了一倍。我已经附上了测试代码。

#pragma mark - Location Update.
/**
 * @description Provides an NSBlockOperation to be executed in an operation queue. This is an attempt to force serial
 * processing
 */
- (NSBlockOperation*)distanceUpdateBlock {
    NSBlockOperation *blockOp = [[NSBlockOperation alloc] init];
    __weak NSBlockOperation * weakOp = blockOp;
    __weak typeof(self) weakSelf = self;
    [blockOp addExecutionBlock:^{
        typeof(weakSelf) blockSafeSelf = weakSelf;
        typeof(weakOp) blockSafeOp = weakOp;

        if (!blockSafeOp.isCancelled) { // Make sure we haven't already been cancelled.
            __block NSDate *startDate = [NSDate date];
            __block BOOL completed = NO;
            void (^replyBlock)(NSDictionary*) =  ^(NSDictionary *message){
                if (!blockSafeOp.isCancelled) {
                    [blockSafeSelf processUserLocationOnWatch:message];

                    double replyTime = [[NSDate date] timeIntervalSinceDate:startDate];
                    NSLog(@"Reply Time: %.03f", replyTime);
                    completed = YES;
                }

            };
            void (^failBlock)(NSError*) =  ^(NSError *error) {
                if (!blockSafeOp.isCancelled) {
                    double replyTime = [[NSDate date] timeIntervalSinceDate:startDate];
                    NSLog(@"Reply Time Fail: %.03f", replyTime);
                    completed = YES;
                }
            };

            [self fetchUserLocationFromIphoneWithReplyHandler:replyBlock errorHandler:failBlock];
            do {
                usleep(10000); // 1/100th second wait to throttle evaluations (Don't worry - in final code I will subclass NSOperation and control when it actually finishes - this is for easy testing.)
            } while (!completed && !blockSafeOp.isCancelled && [blockSafeSelf isWatchReachable]); //(isWatchReachable just makes sure we have a session with the phone and it is reachable).
        }
    }];

    blockOp.completionBlock = ^{
        typeof(weakSelf) blockSafeSelf = weakSelf;
        typeof(weakOp) blockSafeOp = weakOp;
        if (!blockSafeOp.isCancelled) {
            [blockSafeSelf addOperationForLocationUpdate]; // since we are finished - add another operation.
        }
    };

    return blockOp;
}

- (void)addOperationForLocationUpdate {

    [distanceUpdateOperationQueue addOperation:[self distanceUpdateBlock]];
}

- (void)startUpdatingLocation {
    [self addOperationForLocationUpdate];
}

- (void)stopUpdatingLocation {
    [distanceUpdateOperationQueue cancelAllOperations];
}

- (void)fetchUserLocationFromIphoneWithReplyHandler:(nullable void (^)(NSDictionary<NSString *, id> *replyMessage))replyHandler errorHandler:(nullable void (^)(NSError *error))errorHandler {
    if (self.isSessionActive) {
        NSDictionary *message = @{kWatchSessionMessageTag:kWatchSessionMessageUserLocation};

        if (self.isWatchReachable) {
            [[WCSession defaultSession] sendMessage:message
                                       replyHandler:replyHandler
                                       errorHandler:errorHandler
             ];
        } else {
            errorHandler(nil);
        }

    } else {
        [self activateSession];
        errorHandler(nil);
    }
}

iPhone端的处理程序仅获取用户位置并使用编码信息调用replyHandler。

2.2版本的时间日志看起来是这样的(大约一秒钟)

回复时间:0.919

回复时间:0.952

回复时间:0.991

回复时间:0.981

回复时间:0.963

相同的代码在2.1上如下:

回复时间:0.424

回复时间:0.421

回复时间:0.433

回复时间:0.419

此外,我注意到5分钟(300秒)后,那些已经调用了回复处理程序的消息将开始调用错误处理程序。我看到另一个线程中有人也提到了这一点,还有其他人遇到过这种情况并知道原因吗?

因此,问题1 - 是否有人遇到了这种性能减慢并找到了保持replyHandler运行更快或找到更快的更新方式的解决方法?

问题2 - errorHandler在5分钟后被调用的解决方案。

只有一些要排除的事情 - 我已经尽了我的责任,在接收消息和调用replyHandler之间测试了iOS代码。 在iOS 9.2 / 9.3之间处理时间没有变化。 我把它缩小到了这个调用。 实际上,我们以前的版本是现在备份sendMessage的操作队列。所以现在我正在使用这个测试代码强制进行一次调用。 现在我们不再被拥堵,但是单个调用很慢。

1个回答

0
今天我在运行测试时,使用相同的设备和代码,尽管代码没有改变,但现在它的运行速度是最初版本(2.1)的两倍快。日志显示时间范围为0.12-0.2秒。自那以后唯一发生的事情就是软件更新。此外,失败块不再在5分钟后调用。所以这个问题的两个部分都神奇地解决了。我目前使用的是iOS 9.3.4(13G35),手表是2.2.2。似乎在手表和手机之间处理队列的过程中出现了操作系统问题。现在一切都很好。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接