Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion SwiftSynchronized.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "SwiftSynchronized"
s.version = "1.0.1"
s.version = "1.1.0"
s.summary = "Objective-C's @synchronized for Swift, plus performAndWait for NSLock and NSRecursiveLock"
s.description = <<-DESC
@synchronized for Swift, using calls to the Objective-C runtime and providing nearly identical syntax. Also provides performAndWait extension for NSLock and NSRecursiveLock.
Expand Down
12 changes: 6 additions & 6 deletions SwiftSynchronized.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import ObjectiveC
/// - lockToken: An Objective-C object to protect the critical section of code
/// - action: The critical section of code to be protected
/// - Returns: Result of `action()`
public func synchronized<ReturnType>(lockToken: AnyObject, @noescape action: () -> ReturnType) -> ReturnType {
public func synchronized<ReturnType>(_ lockToken: AnyObject, action: () -> ReturnType) -> ReturnType {
return synchronized(lockToken, action: action())
}

Expand All @@ -48,7 +48,7 @@ public func synchronized<ReturnType>(lockToken: AnyObject, @noescape action: ()
/// - lockToken: An Objective-C object to protect the critical section of code
/// - action: The critical section of code to be protected
/// - Returns: Result of `action()`
public func synchronized<ReturnType>(lockToken: AnyObject, @autoclosure action: () -> ReturnType) -> ReturnType {
public func synchronized<ReturnType>(_ lockToken: AnyObject, action: @autoclosure () -> ReturnType) -> ReturnType {
defer { objc_sync_exit(lockToken) }
objc_sync_enter(lockToken)
return action()
Expand All @@ -63,15 +63,15 @@ public protocol LockPerforming: NSLocking {
/// - Parameters:
/// - action: The critical section of code to be protected
/// - Returns: Result of `action()`
func performAndWait<ReturnType>(@noescape action: () -> ReturnType) -> ReturnType
func performAndWait<ReturnType>(_ action: () -> ReturnType) -> ReturnType

/// Protects `action` using `lock()` and `unlock()`.
///
/// lockObj.performAndWait(atomicProperty)
/// - Parameters:
/// - action: The critical section of code to be protected
/// - Returns: Result of `action()`
func performAndWait<ReturnType>(@autoclosure action: () -> ReturnType) -> ReturnType
func performAndWait<ReturnType>(_ action: @autoclosure () -> ReturnType) -> ReturnType
}

extension NSLock: LockPerforming { }
Expand All @@ -81,14 +81,14 @@ public extension LockPerforming {
/// Protects `action` using `lock()` and `unlock()`.
///
/// - SeeAlso: `LockPerforming` protocol
func performAndWait<ReturnType>(@noescape action: () -> ReturnType) -> ReturnType {
func performAndWait<ReturnType>(_ action: () -> ReturnType) -> ReturnType {
return performAndWait(action())
}

/// Protects `action` using `lock()` and `unlock()`.
///
/// - SeeAlso: `LockPerforming` protocol
func performAndWait<ReturnType>(@autoclosure action: () -> ReturnType) -> ReturnType {
func performAndWait<ReturnType>(_ action: @autoclosure () -> ReturnType) -> ReturnType {
defer { unlock() }
lock()
return action()
Expand Down
6 changes: 6 additions & 0 deletions SwiftSynchronized.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,11 @@
TargetAttributes = {
8590CDA11B93B67D00AE74E1 = {
CreatedOnToolsVersion = 7.0;
LastSwiftMigration = 0800;
};
8590CDAB1B93B67D00AE74E1 = {
CreatedOnToolsVersion = 7.0;
LastSwiftMigration = 0800;
};
};
};
Expand Down Expand Up @@ -332,6 +334,7 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
};
name = Debug;
};
Expand All @@ -349,6 +352,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.magicappfactory.SwiftSynchronized;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_VERSION = 3.0;
};
name = Release;
};
Expand All @@ -359,6 +363,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.magicappfactory.SwiftSynchronizedTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
name = Debug;
};
Expand All @@ -369,6 +374,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.magicappfactory.SwiftSynchronizedTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
name = Release;
};
Expand Down
44 changes: 24 additions & 20 deletions SwiftSynchronizedTests/SwiftSynchronizedAutoClosureTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ class SwiftSynchronizedAutoClosureTests: XCTestCase {
// it hasn't been incremented by another operation (when the counter isn't one)

func incrementCounter() {
counter++
counter += 1
}

func decrementCounterIfPossible() {
if counter == 1 {
counter--
counter -= 1
} else {
// Another operation has incremented the counter before we got a chance to decrement it
}
Expand All @@ -54,16 +54,16 @@ class SwiftSynchronizedAutoClosureTests: XCTestCase {

func testWithSwiftSynchronizedAutoclosureExample() {

var blockOps = [NSBlockOperation]()
var blockOps = [BlockOperation]()

for _ in 0...blockOpCount {
let blockOperation = NSBlockOperation() {
let blockOperation = BlockOperation() {
synchronized(self, action: self.performOperation())
}
blockOps.append(blockOperation)
}

let operationQ = NSOperationQueue()
let operationQ = OperationQueue()

operationQ.addOperations(blockOps, waitUntilFinished: true)

Expand All @@ -75,17 +75,19 @@ class SwiftSynchronizedAutoClosureTests: XCTestCase {

func testWithSwiftLockExample() {

var blockOps = [NSBlockOperation]()
var blockOps = [BlockOperation]()
let lock = NSLock()

for _ in 0...blockOpCount {
let blockOperation = NSBlockOperation() {
lock.performAndWait { self.performOperation() }
let blockOperation = BlockOperation {
lock.performAndWait { _ in
self.performOperation()
}
}
blockOps.append(blockOperation)
}

let operationQ = NSOperationQueue()
let operationQ = OperationQueue()

operationQ.addOperations(blockOps, waitUntilFinished: true)

Expand All @@ -96,17 +98,19 @@ class SwiftSynchronizedAutoClosureTests: XCTestCase {

func testWithSwiftRecursiveLockExample() {

var blockOps = [NSBlockOperation]()
var blockOps = [BlockOperation]()
let lock = NSRecursiveLock()

for _ in 0...blockOpCount {
let blockOperation = NSBlockOperation() {
lock.performAndWait { self.performOperation() }
let blockOperation = BlockOperation {
lock.performAndWait { _ in
self.performOperation()
}
}
blockOps.append(blockOperation)
}

let operationQ = NSOperationQueue()
let operationQ = OperationQueue()

operationQ.addOperations(blockOps, waitUntilFinished: true)

Expand All @@ -118,17 +122,17 @@ class SwiftSynchronizedAutoClosureTests: XCTestCase {

func testWithSwiftLockAutoclosureExample() {

var blockOps = [NSBlockOperation]()
var blockOps = [BlockOperation]()
let lock = NSLock()

for _ in 0...blockOpCount {
let blockOperation = NSBlockOperation() {
lock.performAndWait(self.performOperation())
let blockOperation = BlockOperation {
lock.performAndWait( self.performOperation())
}
blockOps.append(blockOperation)
}

let operationQ = NSOperationQueue()
let operationQ = OperationQueue()

operationQ.addOperations(blockOps, waitUntilFinished: true)

Expand All @@ -139,17 +143,17 @@ class SwiftSynchronizedAutoClosureTests: XCTestCase {

func testWithSwiftRecursiveLockAutoclosureExample() {

var blockOps = [NSBlockOperation]()
var blockOps = [BlockOperation]()
let lock = NSRecursiveLock()

for _ in 0...blockOpCount {
let blockOperation = NSBlockOperation() {
let blockOperation = BlockOperation() {
lock.performAndWait(self.performOperation())
}
blockOps.append(blockOperation)
}

let operationQ = NSOperationQueue()
let operationQ = OperationQueue()

operationQ.addOperations(blockOps, waitUntilFinished: true)

Expand Down
24 changes: 12 additions & 12 deletions SwiftSynchronizedTests/SwiftSynchronizedTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ class SwiftSynchronizedTests: XCTestCase {
// it hasn't been incremented by another operation (when the counter isn't one)

func incrementCounter() {
counter++
counter += 1
}

func decrementCounterIfPossible() {
if counter == 1 {
counter--
counter -= 1
} else {
// Another operation has incremented the counter before we got a chance to decrement it
}
Expand All @@ -50,16 +50,16 @@ class SwiftSynchronizedTests: XCTestCase {

func testWithoutSwiftSynchronized() {

var blockOps = [NSBlockOperation]()
var blockOps = [BlockOperation]()

for _ in 0...blockOpCount {
let blockOperation = NSBlockOperation() {
let blockOperation = BlockOperation() {
self.performOperation()
}
blockOps.append(blockOperation)
}

let operationQ = NSOperationQueue()
let operationQ = OperationQueue()

operationQ.addOperations(blockOps, waitUntilFinished: true)
print(counter)
Expand All @@ -72,18 +72,18 @@ class SwiftSynchronizedTests: XCTestCase {

func testWithSwiftSynchronizedExample() {

var blockOps = [NSBlockOperation]()
var blockOps = [BlockOperation]()

for _ in 0...blockOpCount {
let blockOperation = NSBlockOperation() {
synchronized(self) {
let blockOperation = BlockOperation {
synchronized(self) { _ in
self.performOperation()
}
}
blockOps.append(blockOperation)
}

let operationQ = NSOperationQueue()
let operationQ = OperationQueue()

operationQ.addOperations(blockOps, waitUntilFinished: true)

Expand All @@ -94,12 +94,12 @@ class SwiftSynchronizedTests: XCTestCase {

func testtestWithSwiftSynchronizedReturnExample() {

var blockOps = [NSBlockOperation]()
var blockOps = [BlockOperation]()

var localcounter = 0

for _ in 0...blockOpCount {
let blockOperation = NSBlockOperation() {
let blockOperation = BlockOperation() {
localcounter = synchronized(self) {
self.performOperation()
return self.counter
Expand All @@ -108,7 +108,7 @@ class SwiftSynchronizedTests: XCTestCase {
blockOps.append(blockOperation)
}

let operationQ = NSOperationQueue()
let operationQ = OperationQueue()

operationQ.addOperations(blockOps, waitUntilFinished: true)

Expand Down