Nsrunloop's further understanding

Source: Internet
Author: User

An overview of Nsrunloop in iphone app development is what this article is about, and Nsrunloop is a more sophisticated message processing model, and he's better able to abstract and encapsulate the message processing process. That's it. You do not have to deal with some very trivial and low-level specific message processing, in Nsrunloop each message is packaged in input source or timer source, to see the details.

1. What is Nsrunloop

We will often see this code:

    1. -(Ibaction) Start: (ID) sender
    2. {
    3. pagestillloading = YES;
    4. [Nsthread detachnewthreadselector: @selector (loadpageinbackground:) totarget:self Withobject:nil];
    5. [Progress Sethidden:no];
    6. while (pagestillloading) {
    7. [Nsrunloop Currentrunloop] Runmode:nsdefaultrunloopmode beforedate:[nsdate Distantfuture]];
    8. }
    9. [Progress Sethidden:yes];
    10. }
Copy Code

This code is magical, because he will "pause" the code to run, and the program will not be affected because there is a while loop. After [progress Sethidden:no] execution, the entire function would like to pause the same in the loop, and so on loadpageinbackground inside the operation has been completed before let [Progress Sethidden:yes] run. This is an introduction, and the logic is clear. If you don't, you'll need to call [progress Sethidden:yes] in the loadpageinbackground where the load is done, and it looks like the code is not compact and error prone.
[igoogle has the words: The application framework main thread has encapsulated the call to Nsrunloop Runmode:beforedate: it and the while loop form a message pump, constantly acquiring and processing messages; it might be strange for everyone, Since the call to Nsrunloop is already encapsulated in the main thread, why it can be called again, this is the difference between it and the Windows message loop, which can be nested calls. When the While+nsrunloop is called again, the program does not stop executing, and it is still extracting messages Processes the message. This is the same as the nested invocation of active scheduler in Symbian, which is the same as the principle of synchronous action.

So what exactly is Nsrunloop? In fact, the essence of Nsrunloop is a processing mode of message mechanism. If you have a certain understanding of VC + + programming, in Windows, there is a series of very important functions sendmessage,postmessage,getmessage, these are the APIs for message delivery processing.

But when you go into the programming world of cocoa, I don't know if you're too fast and too hasty to overlook this very important issue, cocoa doesn't mention any API for message processing, and developers never have to care about the message delivery process, as if everything was natural, As natural as nature? In cocoa you no longer have to define a macro such as wm_commad_xxx to identify a message, nor do you have to deal with specific messages in switch-case. Is there no message mechanism in cocoa? The answer is no, but Apple has adopted a more sophisticated pattern in designing message processing, which is runloop.

2. How Nsrunloop Works

Let's take a look at the specific working principle of nsrunloop, first of all the official documents provided by the statement, look at the picture:

All the "messages" are added to the Nsrunloop, where the messages are divided into "input source" and "Timer source" and check in the loop if there is an event that needs to happen, and then call the corresponding function if necessary. For a clearer explanation, we will compare VC + + and iOS message processing.

VC + + After all initialization is complete, the program begins to cycle (the code is intercepted from the slides of the MFC programming course for the user Sir):

    1. int Apientry WinMain (hinstance hinstance,hinstance hprevinstance,lpstr lpcmdline,int ncmdshow) {
    2. ...
    3. while (GetMessage (&msg, NULL, 0, 0)) {
    4. if (! TranslateAccelerator (Msg.hwnd, hacceltable, &msg)) {
    5. TranslateMessage (&MSG);
    6. DispatchMessage (&MSG);
    7. }
    8. }
    9. }

You can see that the message is distributed after GetMessage, and the main function in iOS just calls Uiapplicationmain, so we can mind guessing that uiapplicationmain will enter a situation after initialization is complete:

    1. int Uiapplicationmain (...) {
    2. ...
    3. while (running) {
    4. [Nsrunloop Currentrunloop] Runmode:nsdefaultrunloopmode beforedate:[nsdate Distantfuture]];
    5. }
    6. ...
    7. }

So in the Uiapplicationmain is also in constant processing Runloop is the program did not quit. I said just now. Nsrunloop is a more sophisticated message processing mode, he is clever in the message processing process is better abstracted and encapsulated, so that you do not have to deal with some very trivial and low-level specific message processing, in Nsrunloop each message is packaged in the input source, or timer source, invokes the handler of the corresponding object contained in it when it needs to be processed.

So for the outside developer, what you feel is to add Source/timer to the Runloop and then, when appropriate, something like [Receiver action] happens. Even when you don't feel the first half of the process, you just feel a function call to one of your objects.

For example, when UIView is touched, it is called with touchesbegan/touchesmoved and so on, and you might think, "Damn, I don't know where I was told there was a touch message, and these handlers were called!" "So, the message is there, just Runloop has helped you do it!" To prove my point, I intercepted a call stack of debug Touchesbegan,

Blocking Nsoperation threads with Nsrunloop
The development of multithreading is introduced in the use of nsoperationqueue to simplify multithreaded development, and I am here to introduce the use of nsrunloop blocking threads.
The primary use of tasks that are scheduled to be enabled at Nstimer or asynchronous fetching of data, such as socket fetching network data, to block threads until the thread is freed after fetching the data.
The following are the code and execution effects of threads that are not using nsrunloop blocking threads:
Thread class:

#import <Foundation/Foundation.h>
@interface Mytask:nsoperation {
}
@end
#import "MyTask.h"  
@implementation mytask 
-(void) main      
{      
    NSLog (@ "Start thread =%@", self);       
    [nstimer timerwithtimeinterval:2 target:self selector: @selector ( Hiandetime:) userinfo:nil repeats:no];      
}       
-(void) Hiandetime: (ID) sender      
{       
    NSLog (@ "performed Nstimer");      
}       
-(void) dealloc      
{       
    NSLog (@ "Delloc mytask=%@", self);      
     [Super dealloc];      

@end
Threads are added to the queue:


-(void) viewdidload
{
[Super Viewdidload];
Nsoperationqueue *queue=[[nsoperationqueue alloc] init];
MyTask *mytask=[[[mytask alloc] init] autorelease];
[Queue Addoperation:mytask];
MyTask *mytask1=[[[mytask alloc] init] autorelease];
[Queue Addoperation:mytask1];
MyTask *mytask2=[[[mytask alloc] init] autorelease];
[Queue Addoperation:mytask2];
[Queue release];
}
The execution results are:
2011-07-25 09:44:45.393 operationdemo[20676:1803] Start thread =<mytask:0x4b4dea0>
2011-07-25 09:44:45.393 operationdemo[20676:5d03] Start thread =<mytask:0x4b50db0>
2011-07-25 09:44:45.396 operationdemo[20676:1803] Start thread =<mytask:0x4b51070>
2011-07-25 09:44:45.404 operationdemo[20676:6303] Delloc mytask=<mytask:0x4b4dea0>
2011-07-25 09:44:45.404 operationdemo[20676:5d03] Delloc mytask=<mytask:0x4b50db0>
2011-07-25 09:44:45.405 operationdemo[20676:6303] Delloc mytask=<mytask:0x4b51070>
As you can see, there is no way to execute the Nstimer, the thread is released, we are going to execute
Nstimer methods, you should use Nsrunloop to block threads. The following is the modified code:

-(void) Main
{
NSLog (@ "Start thread =%@", self);
Nstimer *timer=[nstimer timerwithtimeinterval:2 target:self selector: @selector (hiandetime) Userinfo:nil Repeats:NO];
[Timer fire];
while (!diddisconnect) {
[[Nsrunloop Currentrunloop] Runmode:nsdefaultrunloopmode beforedate:[nsdate Distantfuture]];
}
}
The results of the implementation are as follows:
2011-07-25 10:07:00.543 operationdemo[21270:1803] Start thread =<mytask:0x4d16380>
2011-07-25 10:07:00.543 operationdemo[21270:5d03] Start thread =<mytask:0x4d17790>
2011-07-25 10:07:00.550 operationdemo[21270:6303] Start thread =<mytask:0x4d17a50>
2011-07-25 10:07:00.550 operationdemo[21270:1803] executed the Nstimer
2011-07-25 10:07:00.551 OPERATIONDEMO[21270:5D03] executed the Nstimer
2011-07-25 10:07:00.552 operationdemo[21270:6303] executed the Nstimer
2011-07-25 10:07:00.556 operationdemo[21270:6503] Delloc mytask=<mytask:0x4d16380>
2011-07-25 10:07:00.557 operationdemo[21270:6303] Delloc mytask=<mytask:0x4d17790>
2011-07-25 10:07:00.557 operationdemo[21270:5d03] Delloc mytask=<mytask:0x4d17a50>
We can use Nsrunloop for thread blocking.

Correct notation for blocking threads using Runloop

Runloop can block threads and wait for other threads to execute before executing.

Like what:

@implementation viewcontroller{
BOOL end;
}
...
– (void) Viewdidload
{
[Super Viewdidload];
NSLog (@ "Start new thread ...");
[Nsthread detachnewthreadselector: @selector (runonnewthread) totarget:self Withobject:nil];
while (!end) {
NSLog (@ "Runloop ...");
[[Nsrunloop Currentrunloop] Runmode:nsdefaultrunloopmode beforedate:[nsdate Distantfuture]];
NSLog (@ "Runloop end.");
}
NSLog (@ "OK.");
}
-(void) runonnewthread{
NSLog (@ "Run for new thread ...");
Sleep (1);
End=yes;
NSLog (@ "end.");
}

However, by doing so, the runtime will find that the statements executed after the while loop will not be executed for a long time.

Does that make it possible to:

[[Nsrunloop Currentrunloop] runmode:nsdefaultrunloopmode beforedate:[nsdate datewithtimeintervalsincenow:0.1] ];

Shorten the sleep time of Runloop, appear to solve the above problems.

However, this is also a problem, runloop objects are often awakened, which violates the Runloop design intention. The role of Runloop is to reduce the CPU to make unnecessary idling, the CPU can sleep in idle time to save power.

So how do you do it? The correct wording is:

-(void) runonnewthread{

NSLog (@ "Run for new thread ...");
Sleep (1);
[Self performselectoronmainthread: @selector (setend) Withobject:nil Waituntildone:no];
NSLog (@ "end.");
}
-(void) setend{
End=yes;
}

See Bold Italic section, to set the variable directly, to send a message to the main thread, execute the method. Problem solved.

To say this, the reason why the statement is deferred after the while loop is that the runloop is not awakened. Because, changing the value of the variable, the Runloop object is not known at all. The duration of the delay is always variable, because there are other events that wake up the main thread at some point, which ends the while loop. Then, sending a message to the main thread wakes up the runloop, so the problem is resolved.

nsrunloop RunMode: nsdefaultrunloopmode/nsrunloopcommonmodes   eg. [[Nsrunloopcurrentrunloop] addtimer:timer formode:nsrunloopcommonmodes]; [[Nsrunloop Currentrunloop] Runmode:nsdefaultrunloopmode beforedate:[nsdate distantfuture]];        Cfrunloop Learning

From Cfrunloop Reference

Cfrunloop monitors sources of input to a task and dispatches control when they become ready for processing.

Examples of input source might include user input devices,network connection,periodic or Timed-delay events,and Asynchrono US callbacks.

Three types of objects can is monitored by a run loop:

Sources (Cfrunloopsource)

Timers (Cfrunlooptimer)

Observers (Cfrunloopobserver)

Each sources,times or observers added to a run loop must is associated with one or more run loop modes.

There is exactly one run loop per thread.

Runloop is an event loop that is used to schedule work and coordinate input events.

Runloop accepts 2 different event sources, input sources (asynchronous event) and timer sources (synchronous event)

When to use Runloop?

1. Use ports or custom input sources to communicate with other threads

2. Using timers in the thread

3. Using Performselector methods in the program

4. Have threads perform a task periodically

Nsrunloop's further understanding

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.