NSOperationQueue 用法

当使用 NSOperationQueue 时,可以通过自定义继承自 NSOperation 的操作类或者使用 NSBlockOperation 来执行任务。下面是几个简单的示例:

1. 使用自定义的 NSOperation 子类:

@interface MyOperation : NSOperation

@end

@implementation MyOperation

- (void)main {
    // 执行任务的代码
    NSLog(@"MyOperation executed");
}

@end

// 创建队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];

// 创建自定义操作对象
MyOperation *operation = [[MyOperation alloc] init];

// 将操作添加到队列中
[queue addOperation:operation];
copy success
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

2. 使用 NSBlockOperation

// 创建队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];

// 创建 NSBlockOperation 对象
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
    // 执行任务的代码
    NSLog(@"Block operation executed");
}];

// 向操作对象添加额外的任务
[operation addExecutionBlock:^{
    NSLog(@"Additional task executed");
}];

// 将操作添加到队列中
[queue addOperation:operation];
copy success
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

3. 添加多个操作到队列并设置依赖关系:

// 创建队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];

// 创建操作1
NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
    NSLog(@"Operation 1 executed");
}];

// 创建操作2
NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
    NSLog(@"Operation 2 executed");
}];

// 创建操作3
NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{
    NSLog(@"Operation 3 executed");
}];

// 设置操作2和操作3依赖于操作1的完成
[operation2 addDependency:operation1];
[operation3 addDependency:operation1];

// 将操作添加到队列中
[queue addOperations:@[operation1, operation2, operation3] waitUntilFinished:YES];
copy success
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

#pragma mark -

@interface TaskOperation : NSOperation

@property (nonatomic, assign) int delay;
@property (nonatomic, assign) long ts;
@property (nonatomic,strong) NSLock *myLock;

- (instancetype)initWithLock:(NSLock *)lock;

@end


@implementation TaskOperation

- (instancetype)initWithLock:(NSLock *)lock {
    self = [super init];
    if (self) {
        _myLock = lock;
    }
    return self;
}

- (void)main {
    // 计算需要等待的秒数
    NSDate *startDate = [NSDate dateWithTimeIntervalSince1970:self.ts];
    
    long cts = [[NSDate date] timeIntervalSince1970];
    
    long waitingTime = self.delay/1000 - (cts - self.ts);
    
    NSLog(@"s_ts: %ld, wait_time: %d, cur_ts: %ld",self.ts, waitingTime, cts);
    
    if (waitingTime > 0) {
        [NSThread sleepForTimeInterval:waitingTime];
    }
    
    NSDateFormatter* formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    NSString* currentDate = [formatter stringFromDate:[NSDate date]];
    [self.myLock lock];
    NSString* message = [NSString stringWithFormat:@"起始时间: %@ 延时: %d 任务完成 %@ | %ld", [formatter stringFromDate: startDate],self.delay,currentDate,(long)[[NSDate date] timeIntervalSince1970]];
    NSLog(@"%@", message);
    
    [NSThread sleepForTimeInterval:1]; //延时 1 秒
    [self.myLock unlock];
}

@end

#pragma mark -


int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // insert code here...
        NSLog(@"Hello, World!");
        
        
        
        // 使用示例
        long delay = 3000; // 延时3000毫秒
        long ts = [[NSDate date] timeIntervalSince1970]; // 当前时间戳
        
        
        NSLock *myLock = [[NSLock alloc] init];
        
        TaskOperation *task = [[TaskOperation alloc] initWithLock:myLock];
        task.delay = delay;
        task.ts = ts;
        
        
        TaskOperation *task2 = [[TaskOperation alloc] initWithLock:myLock];
        task2.delay = delay + 2;
        task2.ts = ts;
        
        TaskOperation *task3 = [[TaskOperation alloc] initWithLock:myLock];
        task3.delay = delay + 3;
        task3.ts = ts + 3;
        
        TaskOperation *task4 = [[TaskOperation alloc] initWithLock:myLock];
        task4.delay = delay + 4;
        task4.ts = ts;
        
        NSOperationQueue *queue = [[NSOperationQueue alloc] init];
        queue.maxConcurrentOperationCount = 2;
        
        [queue addOperation:task];
        [queue addOperation:task2];
        [queue addOperation:task3];
        [queue addOperation:task4];
        
        [queue waitUntilAllOperationsAreFinished];
    }
    return 0;
}

copy success
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97