├── README.md ├── Swift-GCD.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcuserdata │ └── YouXianMing1987@iCloud.com.xcuserdatad │ └── xcdebugger │ └── Breakpoints_v2.xcbkptlist └── Swift-GCD ├── AppDelegate.swift ├── Assets.xcassets └── AppIcon.appiconset │ └── Contents.json ├── Base.lproj ├── LaunchScreen.storyboard └── Main.storyboard ├── GCD ├── GCDGroup.swift ├── GCDQueue.swift ├── GCDQueuePriority.swift ├── GCDSemaphore.swift └── GCDTimer.swift ├── Info.plist └── ViewController.swift /README.md: -------------------------------------------------------------------------------- 1 | # Swift-GCD-Program 2 | 3 | > 需要Objective-C版本GCD的请移步-[Objective-C版本GCD](https://github.com/YouXianMing/GCD-Program) 4 | 5 | ``` 6 | // 7 | // ViewController.swift 8 | // Swift-GCD 9 | // 10 | // Created by YouXianMing on 2017/9/19. 11 | // Copyright © 2017年 TechCode. All rights reserved. 12 | // 13 | import UIKit 14 | 15 | class ViewController: UIViewController { 16 | 17 | override func viewDidLoad() { 18 | 19 | super.viewDidLoad() 20 | } 21 | 22 | private func gcdQueueUse() { 23 | 24 | // Excute in main queue. 25 | GCDQueue.Main.excute { 26 | 27 | print("GCDQueue.Main.excute") 28 | } 29 | 30 | // Excute in global queue. 31 | GCDQueue.Global().excute { 32 | 33 | print("GCDQueue.Global().excute") 34 | } 35 | 36 | // Excute in concurrent queue. 37 | GCDQueue.Concurrent().excute { 38 | 39 | GCDQueue.Global().excuteAndWaitsUntilTheBlockCompletes { 40 | 41 | print("🔥 01") 42 | } 43 | 44 | GCDQueue.Global().excuteAndWaitsUntilTheBlockCompletes { 45 | 46 | print("🔥 02") 47 | } 48 | 49 | GCDQueue.Global().excuteAndWaitsUntilTheBlockCompletes { 50 | 51 | print("🔥 03") 52 | } 53 | 54 | GCDQueue.Global().excuteAndWaitsUntilTheBlockCompletes { 55 | 56 | print("🔥 04") 57 | } 58 | } 59 | 60 | // GCDQueue excute in global queue after delay 2s. 61 | GCDQueue.Global().excuteAfterDelay(2) { 62 | 63 | print("GCDQueue.Global().excuteAfterDelay 2 Seconds") 64 | } 65 | } 66 | 67 | private func gcdSerialQueueUse() { 68 | 69 | let serialQueue = GCDQueue.Serial() 70 | 71 | serialQueue.excute { 72 | 73 | for i in 0..<10 { 74 | 75 | print("🔥" + String(i)) 76 | } 77 | } 78 | 79 | serialQueue.excute { 80 | 81 | for i in 0..<10 { 82 | 83 | print("❄️" + String(i)) 84 | } 85 | } 86 | } 87 | 88 | private func gcdConcurrentQueueUse() { 89 | 90 | let concurrentQueue = GCDQueue.Concurrent() 91 | 92 | concurrentQueue.excute { 93 | 94 | for i in 0..<10 { 95 | 96 | print("🔥" + String(i)) 97 | } 98 | } 99 | 100 | concurrentQueue.excute { 101 | 102 | for i in 0..<10 { 103 | 104 | print("❄️" + String(i)) 105 | } 106 | } 107 | } 108 | 109 | private func gcdGroupNormalUse() { 110 | 111 | // Init group. 112 | let group = GCDGroup() 113 | 114 | // Excute in group. 115 | GCDQueue.Global().excuteInGroup(group) { 116 | 117 | print("Do work A.") 118 | } 119 | 120 | // Excute in group. 121 | GCDQueue.Global().excuteInGroup(group) { 122 | 123 | print("Do work B.") 124 | } 125 | 126 | // Excute in group. 127 | GCDQueue.Global().excuteInGroup(group) { 128 | 129 | print("Do work C.") 130 | } 131 | 132 | // Excute in group. 133 | GCDQueue.Global().excuteInGroup(group) { 134 | 135 | print("Do work D.") 136 | } 137 | 138 | // Notify in queue by group. 139 | group.notifyIn(GCDQueue.Main) { 140 | 141 | print("Finish.") 142 | } 143 | } 144 | 145 | private func gcdGroupEnterAndLeaveUse() { 146 | 147 | // Init group. 148 | let group = GCDGroup() 149 | 150 | group.enter() 151 | group.enter() 152 | group.enter() 153 | 154 | print("Start.") 155 | 156 | GCDQueue.ExcuteInGlobalAfterDelay(3) { 157 | 158 | print("Do work A.") 159 | group.leave() 160 | } 161 | 162 | GCDQueue.ExcuteInGlobalAfterDelay(4) { 163 | 164 | print("Do work B.") 165 | group.leave() 166 | } 167 | 168 | GCDQueue.ExcuteInGlobalAfterDelay(2) { 169 | 170 | print("Do work C.") 171 | group.leave() 172 | } 173 | 174 | // Notify in queue by group. 175 | group.notifyIn(GCDQueue.Main) { 176 | 177 | print("Finish.") 178 | } 179 | } 180 | 181 | private func gcdGroupWaitUse() { 182 | 183 | // Init group. 184 | let group = GCDGroup() 185 | 186 | group.enter() 187 | group.enter() 188 | 189 | print("Start.") 190 | 191 | GCDQueue.ExcuteInGlobalAfterDelay(3) { 192 | 193 | print("Do work A.") 194 | group.leave() 195 | } 196 | 197 | GCDQueue.ExcuteInGlobalAfterDelay(5) { 198 | 199 | print("Do work B.") 200 | group.leave() 201 | } 202 | 203 | let waitSeconds = arc4random() % 2 == 0 ? 4 : 6 204 | print("wait \(waitSeconds) seconds.") 205 | print(group.waitForSeconds(seconds: Float(waitSeconds))) 206 | print("wait finish.") 207 | 208 | // Notify in queue by group. 209 | group.notifyIn(GCDQueue.Main) { 210 | 211 | print("Finish.") 212 | } 213 | } 214 | 215 | 216 | private func gcdSemaphoreWaitForeverUse() { 217 | 218 | // Init semaphore. 219 | let semaphore = GCDSemaphore() 220 | 221 | print("start.") 222 | 223 | GCDQueue.Global().excute { 224 | 225 | semaphore.wait() 226 | print("Done 1") 227 | 228 | semaphore.wait() 229 | print("Done 2") 230 | } 231 | 232 | GCDQueue.Global().excuteAfterDelay(3) { 233 | 234 | semaphore.signal() 235 | } 236 | 237 | GCDQueue.Global().excuteAfterDelay(4) { 238 | 239 | semaphore.signal() 240 | } 241 | } 242 | 243 | private func gcdSemaphoreWaitSecondsUse() { 244 | 245 | // Init semaphore. 246 | let semaphore = GCDSemaphore() 247 | 248 | print("start.") 249 | 250 | GCDQueue.Global().excute { 251 | 252 | _ = semaphore.waitForSeconds(3) 253 | print("Done") 254 | } 255 | 256 | GCDQueue.Global().excuteAfterDelay(5) { 257 | 258 | print("signal") 259 | semaphore.signal() 260 | } 261 | } 262 | 263 | private func gcdTimerUse() { 264 | 265 | let gcdTimer = GCDTimer(in: GCDQueue.Global(), delay: 2, interval: 3) 266 | 267 | print("Start.") 268 | 269 | var count : Int = 0 270 | gcdTimer.setTimerEventHandler {_ in 271 | 272 | count += 1 273 | 274 | print("\(count)") 275 | 276 | if count == 5 { 277 | 278 | print("suspend") 279 | gcdTimer.suspend() 280 | 281 | GCDQueue.ExcuteInGlobalAfterDelay(2.0, { 282 | 283 | print("start") 284 | gcdTimer.start() 285 | }) 286 | } 287 | 288 | if count >= 10 { 289 | 290 | gcdTimer.destroy() 291 | } 292 | } 293 | 294 | gcdTimer.setDestroyEventHandler { 295 | 296 | print("Destroy event.") 297 | } 298 | 299 | gcdTimer.start() 300 | } 301 | } 302 | ``` 303 | 304 | -------------------------------------------------------------------------------- /Swift-GCD.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 48; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | C50983791F72328100C1BDA8 /* GCDQueuePriority.swift in Sources */ = {isa = PBXBuildFile; fileRef = C50983781F72328100C1BDA8 /* GCDQueuePriority.swift */; }; 11 | C509837B1F7239B100C1BDA8 /* GCDTimer.swift in Sources */ = {isa = PBXBuildFile; fileRef = C509837A1F7239B100C1BDA8 /* GCDTimer.swift */; }; 12 | C5B7CF8E1F70EDA800AC4907 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5B7CF8D1F70EDA800AC4907 /* AppDelegate.swift */; }; 13 | C5B7CF901F70EDA900AC4907 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5B7CF8F1F70EDA900AC4907 /* ViewController.swift */; }; 14 | C5B7CF931F70EDA900AC4907 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C5B7CF911F70EDA900AC4907 /* Main.storyboard */; }; 15 | C5B7CF951F70EDA900AC4907 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C5B7CF941F70EDA900AC4907 /* Assets.xcassets */; }; 16 | C5B7CF981F70EDA900AC4907 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C5B7CF961F70EDA900AC4907 /* LaunchScreen.storyboard */; }; 17 | C5B7CFA01F70EDE100AC4907 /* GCDQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5B7CF9F1F70EDE100AC4907 /* GCDQueue.swift */; }; 18 | C5D003651F71031B00561550 /* GCDGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5D003641F71031B00561550 /* GCDGroup.swift */; }; 19 | C5D003671F710C0400561550 /* GCDSemaphore.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5D003661F710C0400561550 /* GCDSemaphore.swift */; }; 20 | /* End PBXBuildFile section */ 21 | 22 | /* Begin PBXFileReference section */ 23 | C50983781F72328100C1BDA8 /* GCDQueuePriority.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GCDQueuePriority.swift; sourceTree = ""; }; 24 | C509837A1F7239B100C1BDA8 /* GCDTimer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GCDTimer.swift; sourceTree = ""; }; 25 | C5B7CF8A1F70EDA800AC4907 /* Swift-GCD.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Swift-GCD.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 26 | C5B7CF8D1F70EDA800AC4907 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 27 | C5B7CF8F1F70EDA900AC4907 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 28 | C5B7CF921F70EDA900AC4907 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 29 | C5B7CF941F70EDA900AC4907 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 30 | C5B7CF971F70EDA900AC4907 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 31 | C5B7CF991F70EDA900AC4907 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 32 | C5B7CF9F1F70EDE100AC4907 /* GCDQueue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GCDQueue.swift; sourceTree = ""; }; 33 | C5D003641F71031B00561550 /* GCDGroup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GCDGroup.swift; sourceTree = ""; }; 34 | C5D003661F710C0400561550 /* GCDSemaphore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GCDSemaphore.swift; sourceTree = ""; }; 35 | /* End PBXFileReference section */ 36 | 37 | /* Begin PBXFrameworksBuildPhase section */ 38 | C5B7CF871F70EDA800AC4907 /* Frameworks */ = { 39 | isa = PBXFrameworksBuildPhase; 40 | buildActionMask = 2147483647; 41 | files = ( 42 | ); 43 | runOnlyForDeploymentPostprocessing = 0; 44 | }; 45 | /* End PBXFrameworksBuildPhase section */ 46 | 47 | /* Begin PBXGroup section */ 48 | C5B7CF811F70EDA800AC4907 = { 49 | isa = PBXGroup; 50 | children = ( 51 | C5B7CF8C1F70EDA800AC4907 /* Swift-GCD */, 52 | C5B7CF8B1F70EDA800AC4907 /* Products */, 53 | ); 54 | sourceTree = ""; 55 | }; 56 | C5B7CF8B1F70EDA800AC4907 /* Products */ = { 57 | isa = PBXGroup; 58 | children = ( 59 | C5B7CF8A1F70EDA800AC4907 /* Swift-GCD.app */, 60 | ); 61 | name = Products; 62 | sourceTree = ""; 63 | }; 64 | C5B7CF8C1F70EDA800AC4907 /* Swift-GCD */ = { 65 | isa = PBXGroup; 66 | children = ( 67 | C5B7CF8D1F70EDA800AC4907 /* AppDelegate.swift */, 68 | C5B7CF8F1F70EDA900AC4907 /* ViewController.swift */, 69 | C5D003681F7116DC00561550 /* GCD */, 70 | C5B7CF941F70EDA900AC4907 /* Assets.xcassets */, 71 | C5B7CF961F70EDA900AC4907 /* LaunchScreen.storyboard */, 72 | C5B7CF991F70EDA900AC4907 /* Info.plist */, 73 | C5B7CF911F70EDA900AC4907 /* Main.storyboard */, 74 | ); 75 | path = "Swift-GCD"; 76 | sourceTree = ""; 77 | }; 78 | C5D003681F7116DC00561550 /* GCD */ = { 79 | isa = PBXGroup; 80 | children = ( 81 | C5B7CF9F1F70EDE100AC4907 /* GCDQueue.swift */, 82 | C5D003641F71031B00561550 /* GCDGroup.swift */, 83 | C5D003661F710C0400561550 /* GCDSemaphore.swift */, 84 | C509837A1F7239B100C1BDA8 /* GCDTimer.swift */, 85 | C50983781F72328100C1BDA8 /* GCDQueuePriority.swift */, 86 | ); 87 | path = GCD; 88 | sourceTree = ""; 89 | }; 90 | /* End PBXGroup section */ 91 | 92 | /* Begin PBXNativeTarget section */ 93 | C5B7CF891F70EDA800AC4907 /* Swift-GCD */ = { 94 | isa = PBXNativeTarget; 95 | buildConfigurationList = C5B7CF9C1F70EDA900AC4907 /* Build configuration list for PBXNativeTarget "Swift-GCD" */; 96 | buildPhases = ( 97 | C5B7CF861F70EDA800AC4907 /* Sources */, 98 | C5B7CF871F70EDA800AC4907 /* Frameworks */, 99 | C5B7CF881F70EDA800AC4907 /* Resources */, 100 | ); 101 | buildRules = ( 102 | ); 103 | dependencies = ( 104 | ); 105 | name = "Swift-GCD"; 106 | productName = "Swift-GCD"; 107 | productReference = C5B7CF8A1F70EDA800AC4907 /* Swift-GCD.app */; 108 | productType = "com.apple.product-type.application"; 109 | }; 110 | /* End PBXNativeTarget section */ 111 | 112 | /* Begin PBXProject section */ 113 | C5B7CF821F70EDA800AC4907 /* Project object */ = { 114 | isa = PBXProject; 115 | attributes = { 116 | LastSwiftUpdateCheck = 0900; 117 | LastUpgradeCheck = 0900; 118 | ORGANIZATIONNAME = TechCode; 119 | TargetAttributes = { 120 | C5B7CF891F70EDA800AC4907 = { 121 | CreatedOnToolsVersion = 9.0; 122 | ProvisioningStyle = Automatic; 123 | }; 124 | }; 125 | }; 126 | buildConfigurationList = C5B7CF851F70EDA800AC4907 /* Build configuration list for PBXProject "Swift-GCD" */; 127 | compatibilityVersion = "Xcode 8.0"; 128 | developmentRegion = en; 129 | hasScannedForEncodings = 0; 130 | knownRegions = ( 131 | en, 132 | Base, 133 | ); 134 | mainGroup = C5B7CF811F70EDA800AC4907; 135 | productRefGroup = C5B7CF8B1F70EDA800AC4907 /* Products */; 136 | projectDirPath = ""; 137 | projectRoot = ""; 138 | targets = ( 139 | C5B7CF891F70EDA800AC4907 /* Swift-GCD */, 140 | ); 141 | }; 142 | /* End PBXProject section */ 143 | 144 | /* Begin PBXResourcesBuildPhase section */ 145 | C5B7CF881F70EDA800AC4907 /* Resources */ = { 146 | isa = PBXResourcesBuildPhase; 147 | buildActionMask = 2147483647; 148 | files = ( 149 | C5B7CF981F70EDA900AC4907 /* LaunchScreen.storyboard in Resources */, 150 | C5B7CF951F70EDA900AC4907 /* Assets.xcassets in Resources */, 151 | C5B7CF931F70EDA900AC4907 /* Main.storyboard in Resources */, 152 | ); 153 | runOnlyForDeploymentPostprocessing = 0; 154 | }; 155 | /* End PBXResourcesBuildPhase section */ 156 | 157 | /* Begin PBXSourcesBuildPhase section */ 158 | C5B7CF861F70EDA800AC4907 /* Sources */ = { 159 | isa = PBXSourcesBuildPhase; 160 | buildActionMask = 2147483647; 161 | files = ( 162 | C5D003651F71031B00561550 /* GCDGroup.swift in Sources */, 163 | C5B7CF901F70EDA900AC4907 /* ViewController.swift in Sources */, 164 | C5B7CFA01F70EDE100AC4907 /* GCDQueue.swift in Sources */, 165 | C5D003671F710C0400561550 /* GCDSemaphore.swift in Sources */, 166 | C50983791F72328100C1BDA8 /* GCDQueuePriority.swift in Sources */, 167 | C5B7CF8E1F70EDA800AC4907 /* AppDelegate.swift in Sources */, 168 | C509837B1F7239B100C1BDA8 /* GCDTimer.swift in Sources */, 169 | ); 170 | runOnlyForDeploymentPostprocessing = 0; 171 | }; 172 | /* End PBXSourcesBuildPhase section */ 173 | 174 | /* Begin PBXVariantGroup section */ 175 | C5B7CF911F70EDA900AC4907 /* Main.storyboard */ = { 176 | isa = PBXVariantGroup; 177 | children = ( 178 | C5B7CF921F70EDA900AC4907 /* Base */, 179 | ); 180 | name = Main.storyboard; 181 | sourceTree = ""; 182 | }; 183 | C5B7CF961F70EDA900AC4907 /* LaunchScreen.storyboard */ = { 184 | isa = PBXVariantGroup; 185 | children = ( 186 | C5B7CF971F70EDA900AC4907 /* Base */, 187 | ); 188 | name = LaunchScreen.storyboard; 189 | sourceTree = ""; 190 | }; 191 | /* End PBXVariantGroup section */ 192 | 193 | /* Begin XCBuildConfiguration section */ 194 | C5B7CF9A1F70EDA900AC4907 /* Debug */ = { 195 | isa = XCBuildConfiguration; 196 | buildSettings = { 197 | ALWAYS_SEARCH_USER_PATHS = NO; 198 | CLANG_ANALYZER_NONNULL = YES; 199 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 200 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 201 | CLANG_CXX_LIBRARY = "libc++"; 202 | CLANG_ENABLE_MODULES = YES; 203 | CLANG_ENABLE_OBJC_ARC = YES; 204 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 205 | CLANG_WARN_BOOL_CONVERSION = YES; 206 | CLANG_WARN_COMMA = YES; 207 | CLANG_WARN_CONSTANT_CONVERSION = YES; 208 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 209 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 210 | CLANG_WARN_EMPTY_BODY = YES; 211 | CLANG_WARN_ENUM_CONVERSION = YES; 212 | CLANG_WARN_INFINITE_RECURSION = YES; 213 | CLANG_WARN_INT_CONVERSION = YES; 214 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 215 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 216 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 217 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 218 | CLANG_WARN_STRICT_PROTOTYPES = YES; 219 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 220 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 221 | CLANG_WARN_UNREACHABLE_CODE = YES; 222 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 223 | CODE_SIGN_IDENTITY = "iPhone Developer"; 224 | COPY_PHASE_STRIP = NO; 225 | DEBUG_INFORMATION_FORMAT = dwarf; 226 | ENABLE_STRICT_OBJC_MSGSEND = YES; 227 | ENABLE_TESTABILITY = YES; 228 | GCC_C_LANGUAGE_STANDARD = gnu11; 229 | GCC_DYNAMIC_NO_PIC = NO; 230 | GCC_NO_COMMON_BLOCKS = YES; 231 | GCC_OPTIMIZATION_LEVEL = 0; 232 | GCC_PREPROCESSOR_DEFINITIONS = ( 233 | "DEBUG=1", 234 | "$(inherited)", 235 | ); 236 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 237 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 238 | GCC_WARN_UNDECLARED_SELECTOR = YES; 239 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 240 | GCC_WARN_UNUSED_FUNCTION = YES; 241 | GCC_WARN_UNUSED_VARIABLE = YES; 242 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 243 | MTL_ENABLE_DEBUG_INFO = YES; 244 | ONLY_ACTIVE_ARCH = YES; 245 | SDKROOT = iphoneos; 246 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 247 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 248 | }; 249 | name = Debug; 250 | }; 251 | C5B7CF9B1F70EDA900AC4907 /* Release */ = { 252 | isa = XCBuildConfiguration; 253 | buildSettings = { 254 | ALWAYS_SEARCH_USER_PATHS = NO; 255 | CLANG_ANALYZER_NONNULL = YES; 256 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 257 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 258 | CLANG_CXX_LIBRARY = "libc++"; 259 | CLANG_ENABLE_MODULES = YES; 260 | CLANG_ENABLE_OBJC_ARC = YES; 261 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 262 | CLANG_WARN_BOOL_CONVERSION = YES; 263 | CLANG_WARN_COMMA = YES; 264 | CLANG_WARN_CONSTANT_CONVERSION = YES; 265 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 266 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 267 | CLANG_WARN_EMPTY_BODY = YES; 268 | CLANG_WARN_ENUM_CONVERSION = YES; 269 | CLANG_WARN_INFINITE_RECURSION = YES; 270 | CLANG_WARN_INT_CONVERSION = YES; 271 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 272 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 273 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 274 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 275 | CLANG_WARN_STRICT_PROTOTYPES = YES; 276 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 277 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 278 | CLANG_WARN_UNREACHABLE_CODE = YES; 279 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 280 | CODE_SIGN_IDENTITY = "iPhone Developer"; 281 | COPY_PHASE_STRIP = NO; 282 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 283 | ENABLE_NS_ASSERTIONS = NO; 284 | ENABLE_STRICT_OBJC_MSGSEND = YES; 285 | GCC_C_LANGUAGE_STANDARD = gnu11; 286 | GCC_NO_COMMON_BLOCKS = YES; 287 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 288 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 289 | GCC_WARN_UNDECLARED_SELECTOR = YES; 290 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 291 | GCC_WARN_UNUSED_FUNCTION = YES; 292 | GCC_WARN_UNUSED_VARIABLE = YES; 293 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 294 | MTL_ENABLE_DEBUG_INFO = NO; 295 | SDKROOT = iphoneos; 296 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 297 | VALIDATE_PRODUCT = YES; 298 | }; 299 | name = Release; 300 | }; 301 | C5B7CF9D1F70EDA900AC4907 /* Debug */ = { 302 | isa = XCBuildConfiguration; 303 | buildSettings = { 304 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 305 | CODE_SIGN_STYLE = Automatic; 306 | DEVELOPMENT_TEAM = HT95VAK372; 307 | INFOPLIST_FILE = "Swift-GCD/Info.plist"; 308 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 309 | PRODUCT_BUNDLE_IDENTIFIER = "com.techCode.Swift-GCD"; 310 | PRODUCT_NAME = "$(TARGET_NAME)"; 311 | SWIFT_VERSION = 4.0; 312 | TARGETED_DEVICE_FAMILY = "1,2"; 313 | }; 314 | name = Debug; 315 | }; 316 | C5B7CF9E1F70EDA900AC4907 /* Release */ = { 317 | isa = XCBuildConfiguration; 318 | buildSettings = { 319 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 320 | CODE_SIGN_STYLE = Automatic; 321 | DEVELOPMENT_TEAM = HT95VAK372; 322 | INFOPLIST_FILE = "Swift-GCD/Info.plist"; 323 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 324 | PRODUCT_BUNDLE_IDENTIFIER = "com.techCode.Swift-GCD"; 325 | PRODUCT_NAME = "$(TARGET_NAME)"; 326 | SWIFT_VERSION = 4.0; 327 | TARGETED_DEVICE_FAMILY = "1,2"; 328 | }; 329 | name = Release; 330 | }; 331 | /* End XCBuildConfiguration section */ 332 | 333 | /* Begin XCConfigurationList section */ 334 | C5B7CF851F70EDA800AC4907 /* Build configuration list for PBXProject "Swift-GCD" */ = { 335 | isa = XCConfigurationList; 336 | buildConfigurations = ( 337 | C5B7CF9A1F70EDA900AC4907 /* Debug */, 338 | C5B7CF9B1F70EDA900AC4907 /* Release */, 339 | ); 340 | defaultConfigurationIsVisible = 0; 341 | defaultConfigurationName = Release; 342 | }; 343 | C5B7CF9C1F70EDA900AC4907 /* Build configuration list for PBXNativeTarget "Swift-GCD" */ = { 344 | isa = XCConfigurationList; 345 | buildConfigurations = ( 346 | C5B7CF9D1F70EDA900AC4907 /* Debug */, 347 | C5B7CF9E1F70EDA900AC4907 /* Release */, 348 | ); 349 | defaultConfigurationIsVisible = 0; 350 | defaultConfigurationName = Release; 351 | }; 352 | /* End XCConfigurationList section */ 353 | }; 354 | rootObject = C5B7CF821F70EDA800AC4907 /* Project object */; 355 | } 356 | -------------------------------------------------------------------------------- /Swift-GCD.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Swift-GCD.xcodeproj/xcuserdata/YouXianMing1987@iCloud.com.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /Swift-GCD/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Swift-GCD 4 | // 5 | // Created by YouXianMing on 2017/9/19. 6 | // Copyright © 2017年 TechCode. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(_ application: UIApplication) { 23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 24 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 25 | } 26 | 27 | func applicationDidEnterBackground(_ application: UIApplication) { 28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | func applicationWillEnterForeground(_ application: UIApplication) { 33 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | func applicationDidBecomeActive(_ application: UIApplication) { 37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 38 | } 39 | 40 | func applicationWillTerminate(_ application: UIApplication) { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /Swift-GCD/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | } 88 | ], 89 | "info" : { 90 | "version" : 1, 91 | "author" : "xcode" 92 | } 93 | } -------------------------------------------------------------------------------- /Swift-GCD/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /Swift-GCD/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /Swift-GCD/GCD/GCDGroup.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GCDGroup.swift 3 | // Swift-GCD 4 | // 5 | // Created by YouXianMing on 2017/9/19. 6 | // Copyright © 2017年 TechCode. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class GCDGroup { 12 | 13 | public let dispatchGroup : DispatchGroup 14 | 15 | init() { 16 | 17 | self.dispatchGroup = DispatchGroup() 18 | } 19 | 20 | /// 在指定的queue里面获取消息 21 | /// 22 | /// - Parameters: 23 | /// - queue: 指定的queue 24 | /// - execute: 执行的block 25 | func notifyIn(_ queue : GCDQueue, execute: @escaping () -> Void) { 26 | 27 | self.dispatchGroup.notify(queue: queue.dispatchQueue, execute: execute) 28 | } 29 | 30 | /// 进入group 31 | func enter() { 32 | 33 | self.dispatchGroup.enter() 34 | } 35 | 36 | /// 从group出来 37 | func leave() { 38 | 39 | self.dispatchGroup.leave() 40 | } 41 | 42 | /// [阻塞操作] 无限等待 43 | func wait() { 44 | 45 | self.dispatchGroup.wait() 46 | } 47 | 48 | /// [阻塞操作] 等待指定的时间 49 | /// 50 | /// - Parameter seconds: 等待的时间,最多精确到1ms 51 | /// - Returns: DispatchTimeoutResult对象 52 | func waitForSeconds(seconds : Float) -> DispatchTimeoutResult { 53 | 54 | return self.dispatchGroup.wait(timeout: .now() + .milliseconds(Int(seconds * 1000))) 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Swift-GCD/GCD/GCDQueue.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GCDQueue.swift 3 | // Swift-GCD 4 | // 5 | // Created by YouXianMing on 2017/9/19. 6 | // Copyright © 2017年 TechCode. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class GCDQueue { 12 | 13 | public let dispatchQueue : DispatchQueue 14 | 15 | init(dispatchQueue : DispatchQueue) { 16 | 17 | self.dispatchQueue = dispatchQueue 18 | } 19 | 20 | // MARK: globalQueue & mainQueue 21 | 22 | /// 获取主线程 23 | public class var Main : GCDQueue { 24 | 25 | return GCDQueue.init(dispatchQueue: DispatchQueue.main) 26 | } 27 | 28 | /// 获取子线程 29 | /// 30 | /// - Parameter priority: 优先级 31 | /// - Returns: 子线程 32 | public class func Global(_ priority : GCDQueuePriority = .DefaultPriority) -> GCDQueue { 33 | 34 | return GCDQueue.init(dispatchQueue: DispatchQueue.global(qos: priority.getDispatchQoSClass())) 35 | } 36 | 37 | // MARK: concurrentQueue & serialQueue 38 | 39 | /// 获取并发线程 40 | /// 41 | /// - Parameters: 42 | /// - label: 线程标签 43 | /// - priority: 优先级 44 | /// - Returns: 并发线程 45 | public class func Concurrent(_ label : String = "", _ priority : GCDQueuePriority = .DefaultPriority) -> GCDQueue { 46 | 47 | return GCDQueue.init(dispatchQueue: DispatchQueue(label: label, qos: priority.getDispatchQoS(), attributes: .concurrent)) 48 | } 49 | 50 | /// 获取串行线程 51 | /// 52 | /// - Parameters: 53 | /// - label: 线程标签 54 | /// - priority: 优先级 55 | /// - Returns: 串行线程 56 | public class func Serial(_ label : String = "", _ priority : GCDQueuePriority = .DefaultPriority) -> GCDQueue { 57 | 58 | return GCDQueue.init(dispatchQueue: DispatchQueue(label: label, qos: priority.getDispatchQoS())) 59 | } 60 | 61 | // MARK: Excute 62 | 63 | /// 异步执行 64 | /// 65 | /// - Parameter excute: 执行的block 66 | public func excute(_ excute : @escaping ()-> Void) { 67 | 68 | dispatchQueue.async(execute: excute) 69 | } 70 | 71 | /// 延时异步执行 72 | /// 73 | /// - Parameters: 74 | /// - seconds: 延时秒数,最多精确到1ms 75 | /// - excute: 执行的block 76 | public func excuteAfterDelay(_ seconds : Float, _ excute : @escaping ()-> Void) { 77 | 78 | dispatchQueue.asyncAfter(deadline: .now() + .milliseconds(Int(seconds * 1000)), execute: excute) 79 | } 80 | 81 | /// 同步执行 82 | /// 83 | /// - Parameter excute: 执行的block 84 | public func excuteAndWaitsUntilTheBlockCompletes(_ excute : @escaping ()-> Void) { 85 | 86 | dispatchQueue.sync(execute: excute) 87 | } 88 | 89 | /// 在group中执行 90 | /// 91 | /// - Parameters: 92 | /// - group: GCDGroup对象 93 | /// - excute: 执行的block 94 | public func excuteInGroup(_ group : GCDGroup, _ excute : @escaping ()-> Void) { 95 | 96 | dispatchQueue.async(group: group.dispatchGroup, execute: excute) 97 | } 98 | 99 | // MARK: Class method for excute 100 | 101 | /// 在主线程执行 102 | /// 103 | /// - Parameter excute: 执行的block 104 | class func ExcuteInMain(_ excute : @escaping ()-> Void) { 105 | 106 | GCDQueue.Main.excute(excute) 107 | } 108 | 109 | /// 在主线程延时执行 110 | /// 111 | /// - Parameters: 112 | /// - seconds: 延时秒数,最多精确到1ms 113 | /// - excute: 执行的block 114 | class func ExcuteInMainAfterDelay(_ seconds : Float, _ excute : @escaping ()-> Void) { 115 | 116 | GCDQueue.Main.excuteAfterDelay(seconds, excute) 117 | } 118 | 119 | /// 在子线程执行 120 | /// 121 | /// - Parameters: 122 | /// - priority: 优先级 123 | /// - excute: 执行的block 124 | class func ExcuteInGlobal(_ priority : GCDQueuePriority = .DefaultPriority, _ excute : @escaping ()-> Void) { 125 | 126 | GCDQueue.Global(priority).excute(excute) 127 | } 128 | 129 | /// 在子线程延时执行 130 | /// 131 | /// - Parameters: 132 | /// - seconds: 延时秒数,最多精确到1ms 133 | /// - excute: 执行的block 134 | class func ExcuteInGlobalAfterDelay(_ seconds : Float, _ excute : @escaping ()-> Void) { 135 | 136 | GCDQueue.Global().excuteAfterDelay(seconds, excute) 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /Swift-GCD/GCD/GCDQueuePriority.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GCDQueuePriority.swift 3 | // Swift-GCD 4 | // 5 | // Created by YouXianMing on 2017/9/20. 6 | // Copyright © 2017年 TechCode. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | enum GCDQueuePriority { 12 | 13 | case BackgroundPriority // DISPATCH_QUEUE_PRIORITY_BACKGROUND 14 | case LowPriority // DISPATCH_QUEUE_PRIORITY_LOW 15 | case DefaultPriority // DISPATCH_QUEUE_PRIORITY_DEFAULT 16 | case HighPriority // DISPATCH_QUEUE_PRIORITY_HIGH 17 | 18 | case userInteractive 19 | case unspecified 20 | 21 | func getDispatchQoSClass() -> DispatchQoS.QoSClass { 22 | 23 | var qos: DispatchQoS.QoSClass 24 | 25 | switch self { 26 | 27 | case GCDQueuePriority.BackgroundPriority: 28 | qos = .background 29 | break 30 | 31 | case GCDQueuePriority.LowPriority: 32 | qos = .utility 33 | break 34 | 35 | case GCDQueuePriority.DefaultPriority: 36 | qos = .default 37 | break 38 | 39 | case GCDQueuePriority.HighPriority: 40 | qos = .userInitiated 41 | break 42 | 43 | case GCDQueuePriority.userInteractive: 44 | qos = .userInteractive 45 | break 46 | 47 | case GCDQueuePriority.unspecified: 48 | qos = .unspecified 49 | break 50 | } 51 | 52 | return qos 53 | } 54 | 55 | func getDispatchQoS() -> DispatchQoS { 56 | 57 | var qos: DispatchQoS 58 | 59 | switch self { 60 | 61 | case GCDQueuePriority.BackgroundPriority: 62 | qos = .background 63 | break 64 | 65 | case GCDQueuePriority.LowPriority: 66 | qos = .utility 67 | break 68 | 69 | case GCDQueuePriority.DefaultPriority: 70 | qos = .default 71 | break 72 | 73 | case GCDQueuePriority.HighPriority: 74 | qos = .userInitiated 75 | break 76 | 77 | case GCDQueuePriority.userInteractive: 78 | qos = .userInteractive 79 | break 80 | 81 | case GCDQueuePriority.unspecified: 82 | qos = .unspecified 83 | break 84 | } 85 | 86 | return qos 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /Swift-GCD/GCD/GCDSemaphore.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GCDSemaphore.swift 3 | // Swift-GCD 4 | // 5 | // Created by YouXianMing on 2017/9/19. 6 | // Copyright © 2017年 TechCode. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class GCDSemaphore { 12 | 13 | public let dispatchSemaphore : DispatchSemaphore 14 | 15 | init(initialSignal : Int = 0) { 16 | 17 | self.dispatchSemaphore = DispatchSemaphore(value: initialSignal) 18 | } 19 | 20 | // MARK: Singal 21 | 22 | /// 发信号 23 | func signal() { 24 | 25 | self.dispatchSemaphore.signal() 26 | } 27 | 28 | // MARK: Wait 29 | 30 | /// [阻塞操作] 无限等待 31 | func wait() { 32 | 33 | self.dispatchSemaphore.wait() 34 | } 35 | 36 | /// [阻塞操作] 等待指定的时间 37 | /// 38 | /// - Parameter seconds: 等待的时间,最多精确到1ms 39 | /// - Returns: DispatchTimeoutResult对象 40 | func waitForSeconds(_ seconds : Float) -> DispatchTimeoutResult { 41 | 42 | return self.dispatchSemaphore.wait(timeout: DispatchTime.now() + .milliseconds(Int(seconds * 1000))) 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Swift-GCD/GCD/GCDTimer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GCDTimer.swift 3 | // Swift-GCD 4 | // 5 | // Created by YouXianMing on 2017/9/20. 6 | // Copyright © 2017年 TechCode. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class GCDTimer { 12 | 13 | public let dispatchSourceTimer : DispatchSourceTimer 14 | 15 | init(in : GCDQueue, delay : Float = 0, interval : Float) { 16 | 17 | dispatchSourceTimer = DispatchSource.makeTimerSource(flags: [], queue: `in`.dispatchQueue) 18 | dispatchSourceTimer.schedule(deadline: .now() + .milliseconds(Int(delay * 1000)), repeating: .milliseconds(Int(interval * 1000))) 19 | } 20 | 21 | /// 设定定时器任务的回调函数 22 | /// 23 | /// - Parameter eventHandler: 回调函数 24 | func setTimerEventHandler(eventHandler: @escaping (GCDTimer)-> Void) { 25 | 26 | dispatchSourceTimer.setEventHandler { 27 | 28 | eventHandler(self) 29 | } 30 | } 31 | 32 | /// 设定定时器销毁时候的回调函数 33 | /// 34 | /// - Parameter eventHandler: 回调函数 35 | func setDestroyEventHandler(eventHandler: @escaping ()-> Void) { 36 | 37 | dispatchSourceTimer.setCancelHandler { 38 | 39 | eventHandler() 40 | } 41 | } 42 | 43 | /// 挂起 44 | func suspend() { 45 | 46 | dispatchSourceTimer.suspend() 47 | } 48 | 49 | /// 开始定时 50 | func start() { 51 | 52 | dispatchSourceTimer.resume() 53 | } 54 | 55 | /// 定时器销毁(执行了此方法后,start就会变得无效) 56 | func destroy() { 57 | 58 | dispatchSourceTimer.cancel() 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Swift-GCD/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /Swift-GCD/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // Swift-GCD 4 | // 5 | // Created by YouXianMing on 2017/9/19. 6 | // Copyright © 2017年 TechCode. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ViewController: UIViewController { 12 | 13 | override func viewDidLoad() { 14 | 15 | super.viewDidLoad() 16 | } 17 | 18 | private func gcdQueueUse() { 19 | 20 | // Excute in main queue. 21 | GCDQueue.Main.excute { 22 | 23 | print("GCDQueue.Main.excute") 24 | } 25 | 26 | // Excute in global queue. 27 | GCDQueue.Global().excute { 28 | 29 | print("GCDQueue.Global().excute") 30 | } 31 | 32 | // Excute in concurrent queue. 33 | GCDQueue.Concurrent().excute { 34 | 35 | GCDQueue.Global().excuteAndWaitsUntilTheBlockCompletes { 36 | 37 | print("🔥 01") 38 | } 39 | 40 | GCDQueue.Global().excuteAndWaitsUntilTheBlockCompletes { 41 | 42 | print("🔥 02") 43 | } 44 | 45 | GCDQueue.Global().excuteAndWaitsUntilTheBlockCompletes { 46 | 47 | print("🔥 03") 48 | } 49 | 50 | GCDQueue.Global().excuteAndWaitsUntilTheBlockCompletes { 51 | 52 | print("🔥 04") 53 | } 54 | } 55 | 56 | // GCDQueue excute in global queue after delay 2s. 57 | GCDQueue.Global().excuteAfterDelay(2) { 58 | 59 | print("GCDQueue.Global().excuteAfterDelay 2 Seconds") 60 | } 61 | } 62 | 63 | private func gcdSerialQueueUse() { 64 | 65 | let serialQueue = GCDQueue.Serial() 66 | 67 | serialQueue.excute { 68 | 69 | for i in 0..<10 { 70 | 71 | print("🔥" + String(i)) 72 | } 73 | } 74 | 75 | serialQueue.excute { 76 | 77 | for i in 0..<10 { 78 | 79 | print("❄️" + String(i)) 80 | } 81 | } 82 | } 83 | 84 | private func gcdConcurrentQueueUse() { 85 | 86 | let concurrentQueue = GCDQueue.Concurrent() 87 | 88 | concurrentQueue.excute { 89 | 90 | for i in 0..<10 { 91 | 92 | print("🔥" + String(i)) 93 | } 94 | } 95 | 96 | concurrentQueue.excute { 97 | 98 | for i in 0..<10 { 99 | 100 | print("❄️" + String(i)) 101 | } 102 | } 103 | } 104 | 105 | private func gcdGroupNormalUse() { 106 | 107 | // Init group. 108 | let group = GCDGroup() 109 | 110 | // Excute in group. 111 | GCDQueue.Global().excuteInGroup(group) { 112 | 113 | print("Do work A.") 114 | } 115 | 116 | // Excute in group. 117 | GCDQueue.Global().excuteInGroup(group) { 118 | 119 | print("Do work B.") 120 | } 121 | 122 | // Excute in group. 123 | GCDQueue.Global().excuteInGroup(group) { 124 | 125 | print("Do work C.") 126 | } 127 | 128 | // Excute in group. 129 | GCDQueue.Global().excuteInGroup(group) { 130 | 131 | print("Do work D.") 132 | } 133 | 134 | // Notify in queue by group. 135 | group.notifyIn(GCDQueue.Main) { 136 | 137 | print("Finish.") 138 | } 139 | } 140 | 141 | private func gcdGroupEnterAndLeaveUse() { 142 | 143 | // Init group. 144 | let group = GCDGroup() 145 | 146 | group.enter() 147 | group.enter() 148 | group.enter() 149 | 150 | print("Start.") 151 | 152 | GCDQueue.ExcuteInGlobalAfterDelay(3) { 153 | 154 | print("Do work A.") 155 | group.leave() 156 | } 157 | 158 | GCDQueue.ExcuteInGlobalAfterDelay(4) { 159 | 160 | print("Do work B.") 161 | group.leave() 162 | } 163 | 164 | GCDQueue.ExcuteInGlobalAfterDelay(2) { 165 | 166 | print("Do work C.") 167 | group.leave() 168 | } 169 | 170 | // Notify in queue by group. 171 | group.notifyIn(GCDQueue.Main) { 172 | 173 | print("Finish.") 174 | } 175 | } 176 | 177 | private func gcdGroupWaitUse() { 178 | 179 | // Init group. 180 | let group = GCDGroup() 181 | 182 | group.enter() 183 | group.enter() 184 | 185 | print("Start.") 186 | 187 | GCDQueue.ExcuteInGlobalAfterDelay(3) { 188 | 189 | print("Do work A.") 190 | group.leave() 191 | } 192 | 193 | GCDQueue.ExcuteInGlobalAfterDelay(5) { 194 | 195 | print("Do work B.") 196 | group.leave() 197 | } 198 | 199 | let waitSeconds = arc4random() % 2 == 0 ? 4 : 6 200 | print("wait \(waitSeconds) seconds.") 201 | print(group.waitForSeconds(seconds: Float(waitSeconds))) 202 | print("wait finish.") 203 | 204 | // Notify in queue by group. 205 | group.notifyIn(GCDQueue.Main) { 206 | 207 | print("Finish.") 208 | } 209 | } 210 | 211 | 212 | private func gcdSemaphoreWaitForeverUse() { 213 | 214 | // Init semaphore. 215 | let semaphore = GCDSemaphore() 216 | 217 | print("start.") 218 | 219 | GCDQueue.Global().excute { 220 | 221 | semaphore.wait() 222 | print("Done 1") 223 | 224 | semaphore.wait() 225 | print("Done 2") 226 | } 227 | 228 | GCDQueue.Global().excuteAfterDelay(3) { 229 | 230 | semaphore.signal() 231 | } 232 | 233 | GCDQueue.Global().excuteAfterDelay(4) { 234 | 235 | semaphore.signal() 236 | } 237 | } 238 | 239 | private func gcdSemaphoreWaitSecondsUse() { 240 | 241 | // Init semaphore. 242 | let semaphore = GCDSemaphore() 243 | 244 | print("start.") 245 | 246 | GCDQueue.Global().excute { 247 | 248 | _ = semaphore.waitForSeconds(3) 249 | print("Done") 250 | } 251 | 252 | GCDQueue.Global().excuteAfterDelay(5) { 253 | 254 | print("signal") 255 | semaphore.signal() 256 | } 257 | } 258 | 259 | private func gcdTimerUse() { 260 | 261 | let gcdTimer = GCDTimer(in: GCDQueue.Global(), delay: 2, interval: 3) 262 | 263 | print("Start.") 264 | 265 | var count : Int = 0 266 | gcdTimer.setTimerEventHandler {_ in 267 | 268 | count += 1 269 | 270 | print("\(count)") 271 | 272 | if count == 5 { 273 | 274 | print("suspend") 275 | gcdTimer.suspend() 276 | 277 | GCDQueue.ExcuteInGlobalAfterDelay(2.0, { 278 | 279 | print("start") 280 | gcdTimer.start() 281 | }) 282 | } 283 | 284 | if count >= 10 { 285 | 286 | gcdTimer.destroy() 287 | } 288 | } 289 | 290 | gcdTimer.setDestroyEventHandler { 291 | 292 | print("Destroy event.") 293 | } 294 | 295 | gcdTimer.start() 296 | } 297 | } 298 | 299 | 300 | 301 | 302 | 303 | --------------------------------------------------------------------------------