Reactive Cocoa Tutorial series, reprinted please indicate the source address http://www.cnblogs.com/sunnyxx/p/3547763.html -- by sunnyxx
The previous article introduced functional programming and RACStream, allowing functions to be connected in tandem. Its specific subclass is also the most important part in RAC programming, RACSignal is the key to making the formula calculate and make it meaningful. This section mainly introduces the mechanism of RACSignal.
RACStream implements the structure of a nested function, such as f (x) = f1 (f2 (f3 (x), but it seems to be a question in the exam paper, no one is doing it. If no result is obtained, this question is meaningless.
Okay, now we can compare this to a one. f (x) results in a piece of chocolate, f1, f2, f3 representing several steps of chocolate production. If this factory is not started, it makes no sense.
In addition, RACSignal references the RAC doc Description:"Signal, Represented by the RACSignal class, is a push-drivenStream ."
I think this "push-driven" must be put together with RACSequence's "pull-driven. In the chocolate factory, push-driven is "", while pull-driven is "". For the factory, the former is an active mode: When chocolate is produced, push is provided to various vendors, the latter is a passive mode: each supplier makes chocolate only when they come to the "pull" product.
Therefore, for the push-driven production model of RACSigna, first of all, when the factory finds that there is no supplier to sign a contract to prepare chocolate, the factory certainly does not need to start production; the factory starts production only when there is more than one dealer preparing to receive the goods. This is the sum of RACSignal, the so-called cold signal and hot signal. Generally, a RACSignal is in the cold state after being created, and is activated only when someone goes to subscribe.
· Event
Next indicates that this Signal produces a value (successfully produced a piece of chocolate)
Completed indicates the end of Signal. The end Signal only indicates the successful completion, without a value (the order of a batch is completed)
Error indicates an error occurred in Signal and ended immediately. (If a machine breaks down, the production line stops running immediately)
The factory director saves QQ from all the suppliers. Whenever one of the above three tasks occurs, QQ is used to send messages to them, so the suppliers can decide what to do based on the production status. After the order is completed or failed, the Director will delete the QQ of the supplier, and there is no need to notify him when sending messages.
__block aNumber = RACSignal *aSignal = [RACSignal createSignal:^ RACDisposable * (<RACSubscriber>++[aSignal subscribeNext:^([aSignal subscribeNext:^(
The above signal references an int variable outside the scope and returns it as the value of the next event during the signal operation. This causes the so-called "Side effects ", the output value is affected by the subscription of the second subscriber.
In my understanding, this is not very authentic. A function in a serious functional programming should not result in inconsistent values of subsequent operations because of computation. However, the actual application is understandable. For example, when a user clicks the "login" button, the login service is written as a RACSignal of login during programming. Of course, the results of the first call to log on are certainly different from those of the second call to log on. Therefore, RAC-based programming reduces most definitions of temporary State values, but not all.
What should we do? I think the best way is to "agree". The RAC design guide introduces the naming rules for a signal:
- Hot signals without side effectsIt is best to use property, such as "textChanged". If you don't quite understand the situation, use the permission as a static property.
- Cold signals without side effectsThe method name of the noun type, such as "-currentText" and "currentModels", also indicates what the return value is. (Note that the next value of RACSignal is of the id type, therefore, the specific return type must be known by conventions)
- Signals with side effectsThis type of method has the same side effects as login. We recommend that you use the method name of the verb type. You can use the method name of the verb to see if it has any side effects, for example, "-loginSignal" and "-saveToFile" probably know that the previous one is likely to have side effects, and the latter one must be saved multiple times without side effects.
Of course, you can also use multicast as an event to share a side effect in some special cases. Next, let's take a look at the official simple example:
RACSignal *networkRequest = [RACSignal createSignal:^(<RACSubscriber>*operation =^(AFHTTPRequestOperation *operation, ^(AFHTTPRequestOperation *operation, NSError * [RACDisposable disposableWithBlock:^RACMulticastConnection *connection =^(^(
A local subscribeNext triggers the creation and execution of AFNetworkingOperation and starts network requests. At this time, a subscriber subscribes to this Signal. It is said that this network request will be "Side effects ", resend the request, but after the above processing, the two subscribers receive the same request content.
RACScheduler is a simple encapsulation of threads in RAC. events can be distributed and executed on the specified scheduler, event distribution and execution are all performed in a default background thread. In most cases, there is no need to change. Some special signal must be called in the main thread, using-deliverOn: the call thread can be switched.
However, it is worth special understanding that:
However, RAC guarantees that no two signal events will ever arrive concurrently. While an being processed, no other events will be delivered. The senders of any other events will be forced to wait until the current has been handled.
It means that the block during subscriber's execution must not be executed concurrently. That is to say, it will not be executed halfway into another thread. It also means there is no need to lock the subscribeXXX block when writing it.
The RACSignal factory has been built and the running mode has been ready. The rest is the chocolate processing technology.
With the foundation of RACStream nesting and assembly, RACSignal is able to process chocolate step by step using a componentized process, from cocoa, milk, sugar and other raw materials to the liquid chocolate suitable for this chocolate, filter, purification, cooling, sandwich, die-pressing, and then to the packaging, a chocolate will be produced. For different types of chocolate, such as wine chocolate, it is just to replace one of the components into a wine heart.
The production component of RACSignal, that is, its various operations. The implementation of a specific business logic is actually to choose the appropriate operation and combine it in the appropriate order.
The user entered textFiled and displayed it in the label above:
RAC(self.outputLabel, text) = self.inputTextField.rac_textSignal;
Now, the requirement is "the user enters more than three letters to output to the label. When there are less than three letters, a prompt is displayed." OK, easy to do:
RAC (self. outputLabel, text) = [[self. inputTextField. rac_textSignal
StartWith: @ "key is> 3"] // The initial value returned by startWith at the beginning
Filter: ^ BOOL (NSString * value ){
Return value. length> 3; // filter: only values that meet the conditions can be transmitted.
}];
The requirement is increased to "show that the input is correct when sunny is entered"
RAC (self. outputLabel, text) = [[self. inputTextField. rac_textSignal
StartWith: @ "key is> 3"] // The initial value returned by startWith at the beginning
Filter: ^ BOOL (NSString * value) {// filter: only values that meet the conditions can be transferred out.
Return value. length> 3;
}]
Map :( NSString * value) {// map converts a value to another value for output
Return [value isEqualToString: @ "sunny"]? @ "Bingo! ": Value;
}];
It can be seen that, after analyzing a business logic, it can be split into a combination of small RACSignal, just like the one-way process for producing chocolate. The chestnuts above slowly feel like a box with a simple answer.
· What then?
In the following sections, we will introduce the operation method of RACSignal. RAC provides many operation methods, which are summarized into several categories: filter, XXX, and XXX.