MST

星途 面试题库

面试题:Objective-C中NSOperationQueue的优先级与依赖关系处理

假设你有一个复杂的任务系统,包含多个NSOperation,其中一些操作依赖于其他操作的完成,同时部分操作有不同的优先级。请描述如何在NSOperationQueue中设置操作的优先级以及处理它们之间的依赖关系,举例说明如何避免循环依赖。并且解释当依赖的操作失败时,依赖它的操作会如何处理。
46.5万 热度难度
编程语言Objective-C

知识考点

AI 面试

面试题答案

一键面试
  1. 设置操作优先级
    • NSOperation中,可以通过设置queuePriority属性来设置操作的优先级。queuePriority是一个枚举类型,有以下几个值:
      • NSOperationQueuePriorityVeryLow:非常低的优先级。
      • NSOperationQueuePriorityLow:低优先级。
      • NSOperationQueuePriorityNormal:普通优先级,默认值。
      • NSOperationQueuePriorityHigh:高优先级。
      • NSOperationQueuePriorityVeryHigh:非常高的优先级。
    • 示例代码:
NSOperation *operation = [[NSOperation alloc] init];
operation.queuePriority = NSOperationQueuePriorityHigh;
  1. 处理依赖关系
    • 可以通过addDependency:方法来设置操作之间的依赖关系。例如,如果操作B依赖于操作A的完成,那么可以这样写:
NSOperation *operationA = [[NSOperation alloc] init];
NSOperation *operationB = [[NSOperation alloc] init];
[operationB addDependency:operationA];
  • 这样,只有当operationA完成后,operationB才会被添加到队列中准备执行。
  1. 避免循环依赖
    • 在设置依赖关系时,要仔细检查确保不会形成循环。例如,如果A依赖BB依赖C,那么C就不能再依赖A
    • 一种常见的避免循环依赖的方法是在设置依赖时,使用一个数据结构(如数组或集合)来记录已经设置的依赖关系。每次设置新的依赖前,检查是否会形成循环。
    • 示例代码(伪代码,简单示意如何检查循环依赖):
NSMutableSet *dependencySet = [NSMutableSet set];
- (BOOL)canAddDependency:(NSOperation *)dependency toOperation:(NSOperation *)operation {
    if ([dependencySet containsObject:operation]) {
        return NO;
    }
    [dependencySet addObject:operation];
    BOOL canAdd = YES;
    for (NSOperation *op in operation.dependencies) {
        canAdd = [self canAddDependency:dependency toOperation:op];
        if (!canAdd) {
            break;
        }
    }
    [dependencySet removeObject:operation];
    return canAdd;
}
  1. 依赖操作失败时的处理
    • 当一个操作失败(通常可以通过设置操作的isFinishedisCancelled属性来模拟失败情况),依赖它的操作不会被执行。NSOperationQueue会自动识别依赖操作的失败状态,并且不会将依赖它的操作添加到可执行队列中。
    • 可以在依赖操作的completionBlock中检查其isCancelled或自定义的错误状态属性,来决定如何处理依赖它的操作。例如,可以选择取消依赖操作,或者根据具体业务逻辑进行重试等操作。
NSOperation *operationA = [[NSOperation alloc] init];
NSOperation *operationB = [[NSOperation alloc] init];
[operationB addDependency:operationA];
operationA.completionBlock = ^{
    if (operationA.isCancelled) {
        [operationB cancel];
    }
};