iOS事件框架:Signals
Signals是一个事件框架能够让你实现观察者模式而不需要使用error prone 和 笨拙NSNotifications或委托delegates.
特性
- Type-safety
- Attach-and-forget observation
- Specify operation queue to observe events on
- Comprehensive Unit Test Coverage
安装
Cocoapods
To integrate Signals into your project add the following to yourPodfile:
pod 'UberSignals', '~> 1.0'
Carthage
To integrate Signals into your project using Carthage add the following to yourCartfile:
github "uber/signals-ios" ~> 1.0
Introduction
NSNotifications are inherently error prone. If a listener doesn’t de-register itself from a notification when it’s deallocated, firing the notification will crash the application. If you refactor the data you send with a notification, the compiler won't warn you but your app might crash at runtime.
NSNotifications are also unnecessarily broad. Anyone can listen in on them which couples separate components in your application implicitly together.
With NSNotifications you register a selector to be invoked when a notification fires. This makes code less readable by separating where you register for notifications and where you handle notifications.
NSNotifications also require a lot of boilerplate code to register unique names to use as notification identifiers.
Signals solves all of the above problems and provides an inline, type-safe and attach-and-forget way to observe events being fired by objects. It is also a great replacement for delegates when there is no need to return data from the delegates.
Usage
Make a class observable by declaring a Signals in its header and implementing it in its initializer:
// Defines a new Signal type. This type is named "NetworkResult", and has two parameters // of type NSData and NSError. Note that the postfix "Signal" is automatically added to // the type name. Also note that only objects are allowed in Signal signatures. CreateSignalType(NetworkResult, NSData *result, NSError *error) // In your header you define the signal @property (nonatomic, readonly) UBSignal<NetworkResultSignal> *onNetworkResult; // In the initializer the instance creates the signal _onNetworkResult = (UBSignal<NetworkResultSignal> *) [[UBSignal alloc] initWithProtocol:@protocol(NetworkResultSignal)]; // Whenever the instance receives a network result (with NSData and NSError), it // fires off the signal. _onNetworkResult.fire(myData, myError);