13

私はそれぞれの長所と短所について多くのことを読んできましたが、デリゲートは通常 1 人のリスナー向けであり、通知は多数のリスナー向けであることを知っています。質問はパフォーマンスについてです。

私はこれを読みました: NSNotificationCenter と委任 (プロトコルを使用)?

私はマイクから通知によって別のクラスに音声信号を送信しています。ここでデリゲートを使用する必要があることはわかっていますが、私の質問は次のとおりです。デリゲートは高速になりますか? フレームレートの問題(減少)があることがわかります。原因がデリゲートの代わりに通知を使用している可能性があるかどうか、または関係がないかどうかを知りたいですか?

4

7 に答える 7

30

パフォーマンスに関心がある人のために、XCTest フレームワークのmeasureBlockAPI を使用して、Swift で簡単なテストを実行しました。簡単に言えば、ループで呼び出すと、違いが大きくなります。

テストに使用するコードは次のとおりです。

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()
    }
}

そしてテストケース:

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)
        }
   }
}

結果:
- 委任:- - - - - - 0.957 秒
- 通知センター: - 3.882 秒

私が試したくだらない代替案

その他の考慮事項として、NSNotificationCenter のパフォーマンスは、特定のイベントに対して存在するリスナーの数と、それらのリスナーによって実行されるコードのパフォーマンスによって明らかに異なる可能性があるということがあります。また、NSNotificationCenter が通知リスナーを同期的にpostNotification呼び出し、呼び出されたのと同じスレッドで呼び出すことも注目に値します。これは、最初に NSNotificationCenter に近づくときに落とし穴になる可能性があります。

(私が経験したように) 1 対多の通信と高いパフォーマンスが必要なシナリオにいる場合は、単にデリゲートの配列を実装することを検討してください。しかし、これのパフォーマンスは実際には最悪のオプションであるため、気にする必要はありません。

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)
        }
   }
}

最終結果:
- 委任:- - - - - - 0.957 秒
- 通知センター: - 3.882 秒
- 複数の委任: - 6.488 秒

于 2015-02-03T22:11:32.940 に答える
1

デリゲートはより高速です。

録画中のフレーム レートの問題は、代理人や通知によるものではありません。これは、UI もレンダリングするメイン スレッドですべてのタスクを実行しているためです。

于 2013-07-29T10:26:00.427 に答える
0

デリゲートは通知よりも高速ですが、どちらも必ずしも必要なものではありません。オーディオの場合、おそらく最初に測定する必要があります。UI を更新する前に何かをより高速に実行する必要がある場合は、GCD ディスパッチまたは NSOperation を介して一部の処理タスクを別のスレッドに移動することを検討する必要があります。

于 2013-07-29T10:42:52.573 に答える