@@ -40,6 +40,8 @@ class TestOperationQueue : XCTestCase {
40
40
( " test_CustomOperationReady " , test_CustomOperationReady) ,
41
41
( " test_DependencyCycleBreak " , test_DependencyCycleBreak) ,
42
42
( " test_Lifecycle " , test_Lifecycle) ,
43
+ ( " test_ConcurrentOperations " , test_ConcurrentOperations) ,
44
+ ( " test_ConcurrentOperationsWithDependenciesAndCompletions " , test_ConcurrentOperationsWithDependenciesAndCompletions) ,
43
45
]
44
46
}
45
47
@@ -699,6 +701,58 @@ class TestOperationQueue : XCTestCase {
699
701
Thread . sleep ( forTimeInterval: 1 ) // Let queue to be deallocated
700
702
XCTAssertNil ( weakQueue, " Queue should be deallocated at this point " )
701
703
}
704
+
705
+ func test_ConcurrentOperations( ) {
706
+ let queue = OperationQueue ( )
707
+ queue. maxConcurrentOperationCount = 2
708
+
709
+ // Running several iterations helps to reveal use-after-dealloc crashes
710
+ for _ in 0 ..< 3 {
711
+ let didRunOp1 = expectation ( description: " Did run first operation " )
712
+ let didRunOp2 = expectation ( description: " Did run second operation " )
713
+
714
+ queue. addOperation {
715
+ self . wait ( for: [ didRunOp2] , timeout: 0.2 )
716
+ didRunOp1. fulfill ( )
717
+ }
718
+ queue. addOperation {
719
+ didRunOp2. fulfill ( )
720
+ }
721
+
722
+ self . wait ( for: [ didRunOp1] , timeout: 0.3 )
723
+ }
724
+ }
725
+
726
+ func test_ConcurrentOperationsWithDependenciesAndCompletions( ) {
727
+ let queue = OperationQueue ( )
728
+ queue. maxConcurrentOperationCount = 2
729
+
730
+ // Running several iterations helps to reveal use-after-dealloc crashes
731
+ for _ in 0 ..< 3 {
732
+ let didRunOp1 = expectation ( description: " Did run first operation " )
733
+ let didRunOp1Completion = expectation ( description: " Did run first operation completion " )
734
+ let didRunOp1Dependency = expectation ( description: " Did run first operation dependency " )
735
+ let didRunOp2 = expectation ( description: " Did run second operation " )
736
+
737
+ let op1 = BlockOperation {
738
+ self . wait ( for: [ didRunOp1Dependency, didRunOp2] , timeout: 0.2 )
739
+ didRunOp1. fulfill ( )
740
+ }
741
+ op1. completionBlock = {
742
+ didRunOp1Completion. fulfill ( )
743
+ }
744
+ let op1Dependency = BlockOperation {
745
+ didRunOp1Dependency. fulfill ( )
746
+ }
747
+ queue. addOperations ( [ op1, op1Dependency] , waitUntilFinished: false )
748
+ queue. addOperation {
749
+ didRunOp2. fulfill ( )
750
+ }
751
+
752
+ self . wait ( for: [ didRunOp1, didRunOp1Completion] , timeout: 0.3 )
753
+ }
754
+ }
755
+
702
756
}
703
757
704
758
class AsyncOperation : Operation {
0 commit comments