For those interested in performance I ran a simple test in swift using the XCTest framework's measureBlock
API. The short answer is that if calling in a loop, the difference will be significant.
Here is the code used to test:
public protocol MyTestClassDelegate: class {
func myTestDelegateCallback()
}
public let TestClassValueChangedNotification = "TestClassNotification"
public class MyViewModel {
public weak var delegate: MyTestClassDelegate?
public init() { }
public func doNotification() {
NSNotificationCenter.defaultCenter().postNotificationName(TestClassValueChangedNotification, object: nil)
}
public func doDelegation(value: Int) {
delegate?.myTestClassDelegateCallback()
}
}
And the Test Cases:
func testPerformanceNotifiction() {
measureBlock { () -> Void in
let testClass = MyTestClass()
for i in 0...100000 {
testClass.doNotification(i)
}
}
}
func testPerformanceDelegation() {
measureBlock { () -> Void in
let testClass = MyTestClass()
testClass.delegate = self
for i in 0...100000 {
testClass.doDelegation(i)
}
}
}
Results:
- Delegation:- - - - - - 0.957 seconds
- Notification Center: - 3.882 seconds
A Crappy Alternative I Tried
Other considerations are that the performance of NSNotificationCenter obviously may vary based on how many listeners there are for a given event, and the performance of the code executed by those listeners. Its also worth noting that NSNotificationCenter calls the notification listeners synchronously, and on the same thread on which postNotification
was invoked, which can be a gotcha when first approaching NSNotificationCenter.
If you find yourself in a scenario, (as I have) where you need one to many communication, and high performance, you might consider simply implementing an array of delegates. But you need not bother, because the performance of this is actually the worst option.
public func doMultipleDelegatation() {
for i in 0..<delegates.count {
delegates[i].myTestDelegateCallback()
})
}
func testPerformanceMultipleDelegation() {
measureBlock { () -> Void in
let testClass = MyTestClass()
testClass.delegates = [self]
for i in 0...100000 {
testClass.doMultipleDelegation(i)
}
}
}
Final Results:
- Delegation:- - - - - - 0.957 seconds
- Notification Center: - 3.882 seconds
- Multiple Delegation: - 6.488 seconds
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…