From 98fb9895fc5eb13a3ee8022cc2005e05bbc2f2a6 Mon Sep 17 00:00:00 2001 From: "Salom, Alexandre" Date: Thu, 22 Sep 2016 16:24:06 +0200 Subject: [PATCH 1/6] Swift 2.3 support --- Dispatcher.xcodeproj/project.pbxproj | 24 +++++++++++++++---- .../xcschemes/Dispatcher.xcscheme | 2 +- DispatcherTests/Info.plist | 2 +- Info.plist | 2 +- 4 files changed, 23 insertions(+), 7 deletions(-) diff --git a/Dispatcher.xcodeproj/project.pbxproj b/Dispatcher.xcodeproj/project.pbxproj index fdd2914..57a2083 100644 --- a/Dispatcher.xcodeproj/project.pbxproj +++ b/Dispatcher.xcodeproj/project.pbxproj @@ -185,15 +185,16 @@ attributes = { LastSwiftMigration = 0700; LastSwiftUpdateCheck = 0700; - LastUpgradeCheck = 0730; + LastUpgradeCheck = 0800; ORGANIZATIONNAME = Larson; TargetAttributes = { 1123A3A619F1404E00BF890F = { CreatedOnToolsVersion = 6.0; + LastSwiftMigration = 0800; }; 1123A3B019F1404F00BF890F = { CreatedOnToolsVersion = 6.0; - TestTargetID = 1123A33519F13F6700BF890F; + LastSwiftMigration = 0800; }; }; }; @@ -279,8 +280,10 @@ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -289,6 +292,7 @@ ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", @@ -322,8 +326,10 @@ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -331,6 +337,7 @@ ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; @@ -340,6 +347,7 @@ IPHONEOS_DEPLOYMENT_TARGET = 8.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; VALIDATE_PRODUCT = YES; }; name = Release; @@ -348,6 +356,7 @@ isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_MODULES = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; @@ -360,9 +369,11 @@ INFOPLIST_FILE = Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "larson.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 2.3; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; @@ -373,6 +384,7 @@ isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_MODULES = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; @@ -381,8 +393,10 @@ INFOPLIST_FILE = Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "larson.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; + SWIFT_VERSION = 2.3; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; @@ -402,8 +416,9 @@ ); INFOPLIST_FILE = DispatcherTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "larson.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/DispatcherExample.app/DispatcherExample"; + SWIFT_VERSION = 2.3; }; name = Debug; }; @@ -416,8 +431,9 @@ ); INFOPLIST_FILE = DispatcherTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "larson.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/DispatcherExample.app/DispatcherExample"; + SWIFT_VERSION = 2.3; }; name = Release; }; diff --git a/Dispatcher.xcodeproj/xcshareddata/xcschemes/Dispatcher.xcscheme b/Dispatcher.xcodeproj/xcshareddata/xcschemes/Dispatcher.xcscheme index 9852075..4bdb8e7 100644 --- a/Dispatcher.xcodeproj/xcshareddata/xcschemes/Dispatcher.xcscheme +++ b/Dispatcher.xcodeproj/xcshareddata/xcschemes/Dispatcher.xcscheme @@ -1,6 +1,6 @@ CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier - larson.$(PRODUCT_NAME:rfc1034identifier) + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/Info.plist b/Info.plist index 40b06aa..d3de8ee 100644 --- a/Info.plist +++ b/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier - larson.$(PRODUCT_NAME:rfc1034identifier) + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName From 51bc5b987f7228afa90db61aabd38b6b9e2a0f1f Mon Sep 17 00:00:00 2001 From: "Salom, Alexandre" Date: Tue, 13 Dec 2016 10:41:36 +0100 Subject: [PATCH 2/6] swift 3.0 --- DispatchGroup.swift | 32 ++++++++------- DispatchQueue.swift | 52 +++++++++++++++--------- DispatchTimer.swift | 50 +++++++++++++---------- Dispatcher.swift | 30 ++++++++------ Dispatcher.xcodeproj/project.pbxproj | 12 +++--- DispatcherTests/DispatchGroupTests.swift | 14 +++---- DispatcherTests/DispatchTimerTests.swift | 48 +++++++++++----------- DispatcherTests/DispatcherTests.swift | 4 +- 8 files changed, 135 insertions(+), 107 deletions(-) diff --git a/DispatchGroup.swift b/DispatchGroup.swift index a8bd0ee..a98699d 100644 --- a/DispatchGroup.swift +++ b/DispatchGroup.swift @@ -2,47 +2,51 @@ import CoreGraphics import Dispatch -public typealias Group = DispatchGroup +public typealias Group = DispatcherGroup -public class DispatchGroup { +open class DispatcherGroup { public init (_ tasks: Int = 0) { for _ in 0.. Void) { - dispatch_group_notify(dispatch_group, gcd.current.dispatch_queue, callback) + open func done (_ callback: @escaping (Void) -> Void) { + guard let current = gcd.current else { + return + } + + dispatch_group.notify(queue: current.dispatch_queue, execute: callback) } - public func wait (delay: CGFloat, _ callback: Void -> Void) { - dispatch_group_wait(dispatch_group, dispatch_time(DISPATCH_TIME_NOW, Int64(delay * CGFloat(NSEC_PER_SEC)))) + open func wait (_ delay: CGFloat, _ callback: (Void) -> Void) { + let _ = dispatch_group.wait(timeout: DispatchTime.now() + Double(Int64(delay * CGFloat(NSEC_PER_SEC))) / Double(NSEC_PER_SEC)) } deinit { assert(tasks == 0, "A DispatchGroup cannot be deallocated when tasks is greater than zero!") } } -public prefix func ++ (group: DispatchGroup) { +public prefix func ++ (group: DispatcherGroup) { objc_sync_enter(group) group.tasks += 1 - dispatch_group_enter(group.dispatch_group) + group.dispatch_group.enter() objc_sync_exit(group) } -public prefix func -- (group: DispatchGroup) { +public prefix func -- (group: DispatcherGroup) { objc_sync_enter(group) group.tasks -= 1 - dispatch_group_leave(group.dispatch_group) + group.dispatch_group.leave() objc_sync_exit(group) } -public postfix func ++ (group: DispatchGroup) { +public postfix func ++ (group: DispatcherGroup) { ++group } -public postfix func -- (group: DispatchGroup) { +public postfix func -- (group: DispatcherGroup) { --group } diff --git a/DispatchQueue.swift b/DispatchQueue.swift index 8ed709d..f289d9e 100644 --- a/DispatchQueue.swift +++ b/DispatchQueue.swift @@ -1,70 +1,82 @@ import Foundation -public typealias Queue = DispatchQueue +public typealias Queue = DispatcherQueue -public class DispatchQueue { +open class DispatcherQueue { // MARK: Public - public let isConcurrent: Bool + open let isConcurrent: Bool - public var isCurrent: Bool { return dispatch_get_specific(&kCurrentQueue) == getMutablePointer(self) } + open var isCurrent: Bool { + return DispatchQueue.getSpecific(key: kCurrentQueue) == getMutablePointer(self) + } - public func async (callback: Void -> Void) { - dispatch_async(dispatch_queue) { callback() } + open func async (_ callback: @escaping (Void) -> Void) { + dispatch_queue.async { callback() } } - public func sync (callback: Void -> Void) { + open func sync (_ callback: (Void) -> Void) { if isCurrent { callback(); return } // prevent deadlocks! - dispatch_sync(dispatch_queue) { callback() } + dispatch_queue.sync { callback() } } - public func async (callback: T -> Void) -> T -> Void { + open func async (_ callback: @escaping (T) -> Void) -> (T) -> Void { return { [weak self] value in if self == nil { return } self!.async { callback(value) } } } - public func sync (callback: T -> Void) -> T -> Void { + open func sync (_ callback: @escaping (T) -> Void) -> (T) -> Void { return { [weak self] value in if self == nil { return } self!.sync { callback(value) } } } - public let dispatch_queue: dispatch_queue_t + open let dispatch_queue: Dispatch.DispatchQueue // MARK: Internal - init (_ queue: dispatch_queue_t) { + init (_ queue: Dispatch.DispatchQueue) { isConcurrent = false dispatch_queue = queue remember() } - - init (_ priority: dispatch_queue_priority_t) { + + init (_ qos: DispatchQoS.QoSClass) { isConcurrent = true - dispatch_queue = dispatch_get_global_queue(priority, 0) + dispatch_queue = DispatchQueue.global(qos: qos) remember() } init (_ concurrent: Bool) { isConcurrent = concurrent - dispatch_queue = dispatch_queue_create(nil, isConcurrent ? DISPATCH_QUEUE_CONCURRENT : DISPATCH_QUEUE_SERIAL) + + // https://bugs.swift.org/browse/SR-1859 + if #available(iOS 10.0, *) { + dispatch_queue = DispatchQueue(label: "", attributes: isConcurrent ? [DispatchQueue.Attributes.concurrent, DispatchQueue.Attributes.initiallyInactive] : [DispatchQueue.Attributes.initiallyInactive]) + } else { + dispatch_queue = DispatchQueue(label: "", attributes: isConcurrent ? [DispatchQueue.Attributes.concurrent] : []) + } remember() } func remember () { - dispatch_queue_set_specific(dispatch_queue, &kCurrentQueue, getMutablePointer(self), nil) + guard let mutablePoiner = getMutablePointer(self) else { + return + } + + dispatch_queue.setSpecific(key: kCurrentQueue, value: mutablePoiner) } } -var kCurrentQueue = 0 +var kCurrentQueue = DispatchSpecificKey() -func getMutablePointer (object: AnyObject) -> UnsafeMutablePointer { - return UnsafeMutablePointer(bitPattern: Int(ObjectIdentifier(object).uintValue)) +func getMutablePointer (_ object: AnyObject) -> UnsafeMutableRawPointer? { + return UnsafeMutableRawPointer(bitPattern: Int(bitPattern: ObjectIdentifier(object))) } diff --git a/DispatchTimer.swift b/DispatchTimer.swift index 7ebc0bf..4b16186 100644 --- a/DispatchTimer.swift +++ b/DispatchTimer.swift @@ -2,15 +2,15 @@ import Foundation import UIKit -public typealias Timer = DispatchTimer +public typealias Timer = DispatcherTimer -public class DispatchTimer { +open class DispatcherTimer { - public convenience init (_ delay: CGFloat, _ callback: Void -> Void) { + public convenience init (_ delay: CGFloat, _ callback: @escaping (Void) -> Void) { self.init(delay, 0, callback) } - public init (_ delay: CGFloat, _ tolerance: CGFloat, _ callback: Void -> Void) { + public init (_ delay: CGFloat, _ tolerance: CGFloat, _ callback: @escaping (Void) -> Void) { self.callback = callback self.tolerance = tolerance @@ -20,57 +20,65 @@ public class DispatchTimer { } self.callbackQueue = gcd.current - self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue.dispatch_queue) + self.timer = DispatchSource.makeTimerSource(flags: DispatchSource.TimerFlags(rawValue: 0), queue: queue.dispatch_queue) - if !gcd.main.isCurrent { dispatch_set_target_queue(queue.dispatch_queue, gcd.current.dispatch_queue) } + if !gcd.main.isCurrent { + if let dispatch_queue = gcd.current?.dispatch_queue { + queue.dispatch_queue.setTarget(queue: dispatch_queue) + } + } let delay_ns = delay * CGFloat(NSEC_PER_SEC) - let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay_ns)) - dispatch_source_set_timer(timer, time, UInt64(delay_ns), UInt64(tolerance * CGFloat(NSEC_PER_SEC))) - dispatch_source_set_event_handler(timer) { [weak self] in let _ = self?.fire() } - dispatch_resume(timer) + let time = DispatchTime.now() + Double(Int64(delay_ns)) / Double(NSEC_PER_SEC) + + let interval = DispatchTimeInterval.nanoseconds(Int(delay_ns)) + let leeway = DispatchTimeInterval.nanoseconds(Int(UInt64(tolerance * CGFloat(NSEC_PER_SEC)))) + + timer?.scheduleRepeating(deadline: time, interval: interval, leeway: leeway) + timer?.setEventHandler { [weak self] in let _ = self?.fire() } + timer?.resume() } // MARK: Read-only - public let tolerance: CGFloat + open let tolerance: CGFloat - public let callback: Void -> Void + open let callback: (Void) -> Void // MARK: Instance methods - public func doRepeat (times: UInt! = nil) { + open func doRepeat (_ times: UInt! = nil) { isRepeating = true repeatsLeft = times != nil ? Int(times) : -1 } - public func autorelease () { + open func autorelease () { isAutoReleased = true autoReleasedTimers[ObjectIdentifier(self)] = self } - public func fire () { + open func fire () { if OSAtomicAnd32OrigBarrier(1, &invalidated) == 1 { return } - callbackQueue.sync(callback) + callbackQueue?.sync(callback) if isRepeating && repeatsLeft > 0 { repeatsLeft -= 1 } if !isRepeating || repeatsLeft == 0 { stop() } } - public func stop () { + open func stop () { if OSAtomicTestAndSetBarrier(7, &invalidated) { return } - queue.sync({dispatch_source_cancel(self.timer)}) + queue.sync({self.timer?.cancel()}) if isAutoReleased { autoReleasedTimers[ObjectIdentifier(self)] = nil } } // MARK: Internal - var timer: dispatch_source_t! + var timer: DispatchSourceTimer? - let queue: DispatchQueue = gcd.serial() + let queue: DispatcherQueue = gcd.serial() - var callbackQueue: DispatchQueue! + var callbackQueue: DispatcherQueue? var invalidated: UInt32 = 0 diff --git a/Dispatcher.swift b/Dispatcher.swift index 431b4fc..80a7a3b 100644 --- a/Dispatcher.swift +++ b/Dispatcher.swift @@ -3,27 +3,31 @@ import Dispatch public let gcd = Dispatcher() -public class Dispatcher : DispatchQueue { +public class Dispatcher : DispatcherQueue { - public var current: DispatchQueue { - return Unmanaged.fromOpaque(COpaquePointer(dispatch_get_specific(&kCurrentQueue))).takeUnretainedValue() + public var current: DispatcherQueue? { + guard let unsafeRawPoiner = DispatchQueue.getSpecific(key: kCurrentQueue) else { + return nil + } + + return Unmanaged.fromOpaque(unsafeRawPoiner).takeUnretainedValue() } - public let main = DispatchQueue(dispatch_get_main_queue()) + public let main = DispatcherQueue(DispatchQueue.main) - public let high = DispatchQueue(DISPATCH_QUEUE_PRIORITY_HIGH) + public let high = DispatcherQueue(.userInitiated) - public let low = DispatchQueue(DISPATCH_QUEUE_PRIORITY_LOW) + public let low = DispatcherQueue(.utility) - public let background = DispatchQueue(DISPATCH_QUEUE_PRIORITY_BACKGROUND) + public let background = DispatcherQueue(.background) - public func serial () -> DispatchQueue { - return DispatchQueue(false) + public func serial () -> DispatcherQueue { + return DispatcherQueue(false) } - public func concurrent () -> DispatchQueue { - return DispatchQueue(true) + public func concurrent () -> DispatcherQueue { + return DispatcherQueue(true) } - init () { super.init(DISPATCH_QUEUE_PRIORITY_DEFAULT) } -} \ No newline at end of file + init () { super.init(.default) } +} diff --git a/Dispatcher.xcodeproj/project.pbxproj b/Dispatcher.xcodeproj/project.pbxproj index 57a2083..7ace249 100644 --- a/Dispatcher.xcodeproj/project.pbxproj +++ b/Dispatcher.xcodeproj/project.pbxproj @@ -190,11 +190,11 @@ TargetAttributes = { 1123A3A619F1404E00BF890F = { CreatedOnToolsVersion = 6.0; - LastSwiftMigration = 0800; + LastSwiftMigration = 0810; }; 1123A3B019F1404F00BF890F = { CreatedOnToolsVersion = 6.0; - LastSwiftMigration = 0800; + LastSwiftMigration = 0810; }; }; }; @@ -373,7 +373,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 2.3; + SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; @@ -396,7 +396,7 @@ PRODUCT_BUNDLE_IDENTIFIER = "larson.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; - SWIFT_VERSION = 2.3; + SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; @@ -418,7 +418,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "larson.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 2.3; + SWIFT_VERSION = 3.0; }; name = Debug; }; @@ -433,7 +433,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "larson.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 2.3; + SWIFT_VERSION = 3.0; }; name = Release; }; diff --git a/DispatcherTests/DispatchGroupTests.swift b/DispatcherTests/DispatchGroupTests.swift index 73534a6..5826c58 100644 --- a/DispatcherTests/DispatchGroupTests.swift +++ b/DispatcherTests/DispatchGroupTests.swift @@ -5,7 +5,7 @@ import Dispatcher class DispatchGroupTests: XCTestCase { - var group: DispatchGroup! + var group: DispatcherGroup! override func tearDown() { group = nil @@ -13,9 +13,9 @@ class DispatchGroupTests: XCTestCase { } func testDispatchGroup () { - let expectation = expectationWithDescription("") + let expectation = self.expectation(description: "") - group = DispatchGroup() + group = DispatcherGroup() group++ @@ -23,13 +23,13 @@ class DispatchGroupTests: XCTestCase { group-- - waitForExpectationsWithTimeout(1) { XCTAssertNil($0) } + waitForExpectations(timeout: 1) { XCTAssertNil($0) } } func testThreadSafety () { - let expectation = expectationWithDescription("") + let expectation = self.expectation(description: "") - group = DispatchGroup(2) + group = DispatcherGroup(2) gcd.async { self.group-- @@ -40,6 +40,6 @@ class DispatchGroupTests: XCTestCase { group.done(expectation.fulfill) - waitForExpectationsWithTimeout(1) { XCTAssertNil($0) } + waitForExpectations(timeout: 1) { XCTAssertNil($0) } } } diff --git a/DispatcherTests/DispatchTimerTests.swift b/DispatcherTests/DispatchTimerTests.swift index 2d07a59..70aa61e 100644 --- a/DispatcherTests/DispatchTimerTests.swift +++ b/DispatcherTests/DispatchTimerTests.swift @@ -5,7 +5,7 @@ import Dispatcher class DispatchTimerTests: XCTestCase { - var timer: DispatchTimer! + var timer: DispatcherTimer! var calls = 0 var view: UIView! @@ -16,29 +16,29 @@ class DispatchTimerTests: XCTestCase { } func testDispatchTimer () { - let expectation = expectationWithDescription("") + let expectation = self.expectation(description: "") - timer = DispatchTimer(1, expectation.fulfill) + timer = DispatcherTimer(1, expectation.fulfill) - waitForExpectationsWithTimeout(1.1, handler: nil) + waitForExpectations(timeout: 1.1, handler: nil) } func testCallbackQueue () { - let e = expectationWithDescription("") + let e = expectation(description: "") gcd.async { - self.timer = DispatchTimer(0.1) { + self.timer = DispatcherTimer(0.1) { XCTAssert(gcd.isCurrent) e.fulfill() } } - waitForExpectationsWithTimeout(0.3, handler: nil) + waitForExpectations(timeout: 0.3, handler: nil) } func testFire () { - timer = DispatchTimer(1, {self.calls += 1}) + timer = DispatcherTimer(1, {self.calls += 1}) timer.fire() @@ -48,9 +48,9 @@ class DispatchTimerTests: XCTestCase { } func testFiniteRepeatingTimer () { - let expectation = expectationWithDescription("") + let expectation = self.expectation(description: "") - timer = DispatchTimer(0.25) { + timer = DispatcherTimer(0.25) { self.calls += 1 if self.calls == 2 { expectation.fulfill() @@ -59,13 +59,13 @@ class DispatchTimerTests: XCTestCase { timer.doRepeat(2) - waitForExpectationsWithTimeout(1, handler: nil) + waitForExpectations(timeout: 1, handler: nil) } func testInfiniteRepeatingTimer () { - let expectation = expectationWithDescription("") + let expectation = self.expectation(description: "") - timer = DispatchTimer(0.1) { + timer = DispatcherTimer(0.1) { self.calls += 1 if self.calls == 5 { expectation.fulfill() @@ -74,37 +74,37 @@ class DispatchTimerTests: XCTestCase { timer.doRepeat() - waitForExpectationsWithTimeout(1, handler: nil) + waitForExpectations(timeout: 1, handler: nil) } func testAutoClosureTimer () { - let expectation = expectationWithDescription("") + let expectation = self.expectation(description: "") - timer = DispatchTimer(0.1, {expectation.fulfill()}) + timer = DispatcherTimer(0.1, {expectation.fulfill()}) - waitForExpectationsWithTimeout(1, handler: nil) + waitForExpectations(timeout: 1, handler: nil) } func testAutoReleasedTimer () { - let expectation = expectationWithDescription("") + let expectation = self.expectation(description: "") - DispatchTimer(0.5, {expectation.fulfill()}).autorelease() + DispatcherTimer(0.5, {expectation.fulfill()}).autorelease() - waitForExpectationsWithTimeout(1, handler: nil) + waitForExpectations(timeout: 1, handler: nil) } func testUnretainedTimer () { - let _ = DispatchTimer(0.1, {self.calls += 1}) - timer = DispatchTimer(0.2, {XCTAssert(self.calls == 0)}) + let _ = DispatcherTimer(0.1, {self.calls += 1}) + timer = DispatcherTimer(0.2, {XCTAssert(self.calls == 0)}) } func testThreadSafety () { - let expectation = expectationWithDescription("") + let expectation = self.expectation(description: "") gcd.async { self.timer = Timer(0.5, gcd.main.sync({expectation.fulfill()})) } - waitForExpectationsWithTimeout(1, handler: nil) + waitForExpectations(timeout: 1, handler: nil) } } diff --git a/DispatcherTests/DispatcherTests.swift b/DispatcherTests/DispatcherTests.swift index 3343d63..3bb60ce 100644 --- a/DispatcherTests/DispatcherTests.swift +++ b/DispatcherTests/DispatcherTests.swift @@ -43,10 +43,10 @@ class DispatcherTests: XCTestCase { } func testAsyncInAsync () { - let expectation = expectationWithDescription("") + let expectation = self.expectation(description: "") gcd.main.async({gcd.main.async({expectation.fulfill()})}) - waitForExpectationsWithTimeout(1, handler: nil) + waitForExpectations(timeout: 1, handler: nil) } } From 623890f8667ba49c7f3466cb437962afa1f00d96 Mon Sep 17 00:00:00 2001 From: "Salom, Alexandre" Date: Tue, 13 Dec 2016 10:50:30 +0100 Subject: [PATCH 3/6] @escaping --- DispatchQueue.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DispatchQueue.swift b/DispatchQueue.swift index f289d9e..ccf7a85 100644 --- a/DispatchQueue.swift +++ b/DispatchQueue.swift @@ -17,7 +17,7 @@ open class DispatcherQueue { dispatch_queue.async { callback() } } - open func sync (_ callback: (Void) -> Void) { + open func sync (_ callback: @escaping (Void) -> Void) { if isCurrent { callback(); return } // prevent deadlocks! dispatch_queue.sync { callback() } } From 98d717877c551eb7118e18773c5c1e39b225e489 Mon Sep 17 00:00:00 2001 From: "Salom, Alexandre" Date: Tue, 13 Dec 2016 14:03:54 +0100 Subject: [PATCH 4/6] PR remarks --- DispatchGroup.swift | 2 -- DispatchQueue.swift | 28 +++++++++++------------- DispatchTimer.swift | 6 ++--- Dispatcher.swift | 14 ++++++------ DispatcherTests/DispatchTimerTests.swift | 2 +- 5 files changed, 23 insertions(+), 29 deletions(-) diff --git a/DispatchGroup.swift b/DispatchGroup.swift index a98699d..551e91b 100644 --- a/DispatchGroup.swift +++ b/DispatchGroup.swift @@ -2,8 +2,6 @@ import CoreGraphics import Dispatch -public typealias Group = DispatcherGroup - open class DispatcherGroup { public init (_ tasks: Int = 0) { diff --git a/DispatchQueue.swift b/DispatchQueue.swift index ccf7a85..b37b110 100644 --- a/DispatchQueue.swift +++ b/DispatchQueue.swift @@ -1,8 +1,6 @@ import Foundation -public typealias Queue = DispatcherQueue - open class DispatcherQueue { // MARK: Public @@ -14,47 +12,47 @@ open class DispatcherQueue { } open func async (_ callback: @escaping (Void) -> Void) { - dispatch_queue.async { callback() } + dispatch_queue.async(execute: callback) } - open func sync (_ callback: @escaping (Void) -> Void) { + open func sync (_ callback: (Void) -> Void) { if isCurrent { callback(); return } // prevent deadlocks! - dispatch_queue.sync { callback() } + dispatch_queue.sync(execute: callback) } open func async (_ callback: @escaping (T) -> Void) -> (T) -> Void { return { [weak self] value in - if self == nil { return } - self!.async { callback(value) } + guard let strongSelf = self else { return } + strongSelf.async { callback(value) } } } open func sync (_ callback: @escaping (T) -> Void) -> (T) -> Void { return { [weak self] value in - if self == nil { return } - self!.sync { callback(value) } + guard let strongSelf = self else { return } + strongSelf.sync { callback(value) } } } - open let dispatch_queue: Dispatch.DispatchQueue + open let dispatch_queue: DispatchQueue // MARK: Internal - init (_ queue: Dispatch.DispatchQueue) { + init (queue: DispatchQueue) { isConcurrent = false dispatch_queue = queue remember() } - init (_ qos: DispatchQoS.QoSClass) { + init (qos: DispatchQoS.QoSClass) { isConcurrent = true dispatch_queue = DispatchQueue.global(qos: qos) remember() } - init (_ concurrent: Bool) { + init (concurrent: Bool) { isConcurrent = concurrent // https://bugs.swift.org/browse/SR-1859 @@ -67,11 +65,11 @@ open class DispatcherQueue { } func remember () { - guard let mutablePoiner = getMutablePointer(self) else { + guard let mutablePointer = getMutablePointer(self) else { return } - dispatch_queue.setSpecific(key: kCurrentQueue, value: mutablePoiner) + dispatch_queue.setSpecific(key: kCurrentQueue, value: mutablePointer) } } diff --git a/DispatchTimer.swift b/DispatchTimer.swift index 4b16186..4d815c8 100644 --- a/DispatchTimer.swift +++ b/DispatchTimer.swift @@ -2,8 +2,6 @@ import Foundation import UIKit -public typealias Timer = DispatcherTimer - open class DispatcherTimer { public convenience init (_ delay: CGFloat, _ callback: @escaping (Void) -> Void) { @@ -29,7 +27,7 @@ open class DispatcherTimer { } let delay_ns = delay * CGFloat(NSEC_PER_SEC) - let time = DispatchTime.now() + Double(Int64(delay_ns)) / Double(NSEC_PER_SEC) + let time = DispatchTime.now() + Double(delay) let interval = DispatchTimeInterval.nanoseconds(Int(delay_ns)) let leeway = DispatchTimeInterval.nanoseconds(Int(UInt64(tolerance * CGFloat(NSEC_PER_SEC)))) @@ -93,4 +91,4 @@ open class DispatcherTimer { } } -var autoReleasedTimers = [ObjectIdentifier:Timer]() +var autoReleasedTimers = [ObjectIdentifier:DispatcherTimer]() diff --git a/Dispatcher.swift b/Dispatcher.swift index 80a7a3b..93ac1de 100644 --- a/Dispatcher.swift +++ b/Dispatcher.swift @@ -13,21 +13,21 @@ public class Dispatcher : DispatcherQueue { return Unmanaged.fromOpaque(unsafeRawPoiner).takeUnretainedValue() } - public let main = DispatcherQueue(DispatchQueue.main) + public let main = DispatcherQueue(queue: DispatchQueue.main) - public let high = DispatcherQueue(.userInitiated) + public let high = DispatcherQueue(qos: .userInitiated) - public let low = DispatcherQueue(.utility) + public let low = DispatcherQueue(qos: .utility) - public let background = DispatcherQueue(.background) + public let background = DispatcherQueue(qos: .background) public func serial () -> DispatcherQueue { - return DispatcherQueue(false) + return DispatcherQueue(concurrent: false) } public func concurrent () -> DispatcherQueue { - return DispatcherQueue(true) + return DispatcherQueue(concurrent: true) } - init () { super.init(.default) } + init () { super.init(qos: .default) } } diff --git a/DispatcherTests/DispatchTimerTests.swift b/DispatcherTests/DispatchTimerTests.swift index 70aa61e..d736775 100644 --- a/DispatcherTests/DispatchTimerTests.swift +++ b/DispatcherTests/DispatchTimerTests.swift @@ -102,7 +102,7 @@ class DispatchTimerTests: XCTestCase { let expectation = self.expectation(description: "") gcd.async { - self.timer = Timer(0.5, gcd.main.sync({expectation.fulfill()})) + self.timer = DispatcherTimer(0.5, gcd.main.sync({expectation.fulfill()})) } waitForExpectations(timeout: 1, handler: nil) From 83b6360facd436b492384c692f468faf8186c164 Mon Sep 17 00:00:00 2001 From: "Salom, Alexandre" Date: Tue, 13 Dec 2016 15:52:53 +0100 Subject: [PATCH 5/6] using labels --- DispatchQueue.swift | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/DispatchQueue.swift b/DispatchQueue.swift index b37b110..47fb15b 100644 --- a/DispatchQueue.swift +++ b/DispatchQueue.swift @@ -3,6 +3,8 @@ import Foundation open class DispatcherQueue { + private static let Label = "com.mobilenatives.dispatcher" + // MARK: Public open let isConcurrent: Bool @@ -57,9 +59,9 @@ open class DispatcherQueue { // https://bugs.swift.org/browse/SR-1859 if #available(iOS 10.0, *) { - dispatch_queue = DispatchQueue(label: "", attributes: isConcurrent ? [DispatchQueue.Attributes.concurrent, DispatchQueue.Attributes.initiallyInactive] : [DispatchQueue.Attributes.initiallyInactive]) + dispatch_queue = DispatchQueue(label: DispatcherQueue.Label, attributes: isConcurrent ? [DispatchQueue.Attributes.concurrent, DispatchQueue.Attributes.initiallyInactive] : [DispatchQueue.Attributes.initiallyInactive]) } else { - dispatch_queue = DispatchQueue(label: "", attributes: isConcurrent ? [DispatchQueue.Attributes.concurrent] : []) + dispatch_queue = isConcurrent ? DispatchQueue(label: DispatcherQueue.Label, attributes: [DispatchQueue.Attributes.concurrent]) : DispatchQueue(label: DispatcherQueue.Label) } remember() } From 7e7de416de59b119d0403efd460ff546b1a1dbd2 Mon Sep 17 00:00:00 2001 From: asalom Date: Tue, 2 May 2017 14:46:57 +0200 Subject: [PATCH 6/6] Application extensions friendly --- Dispatcher.xcodeproj/project.pbxproj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Dispatcher.xcodeproj/project.pbxproj b/Dispatcher.xcodeproj/project.pbxproj index 7ace249..e5ec627 100644 --- a/Dispatcher.xcodeproj/project.pbxproj +++ b/Dispatcher.xcodeproj/project.pbxproj @@ -355,6 +355,7 @@ 1123A3C019F1404F00BF890F /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ENABLE_MODULES = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; CURRENT_PROJECT_VERSION = 1; @@ -383,6 +384,7 @@ 1123A3C119F1404F00BF890F /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ENABLE_MODULES = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; CURRENT_PROJECT_VERSION = 1;