IOS autorelease Runloop

Source: Internet
Author: User

Learning about iphone Development, when autorelease release has always been a problem that bothers me, is that most documents mention delayed release, but the latency is very vague, 5s is called latency or 5min. So I always feel worried that I used to mark the Autorelease object when it was released because it didn't stick. Recently checked autorelease exactly when release, found and Runloop about, and then check runloop found a lot of explanations, but the feeling probably means Runloop is the event cycle, the event contains: Touch screen, Nstimer, etc., Each thread creates a Runloop loop, and for each runloop, the system implicitly creates a autorelease pool so that all the release pool forms a stack structure like callstack, At the end of each runloop, the Autorelease pool at the top of the current stack is destroyed so that each object in the pool is release. Here is a specific explanation:

1, First look autorelease: (Source: http://blog.csdn.net/xxq_2011/article/details/7334735)

1. If you can really understand autorelease, then you understand the memory management of Objective C. Autorelease actually only delays the call to release, and for each autorelease, the system simply puts the object into the current Autorelease pool, and when that pool is released, All of the object in the pool is invoked to release.
In fact, the objects returned by such constructors as [NSString stringwithformat:1.0] are autorelease.

2. Autorelease pool to avoid frequent application/release of memory (which is the role of pool). This should be relatively easy to understand.

Conclusion: (1) We must pay attention to the life cycle of autorelease pool, understand the runloop and avoid using it after the object is released.

(2) [NSString stringWithFormat] The object returned by this type of function does not need to release itself, it has been autorelease, and if you want to use it as a global object, you must retain it yourself. Release again when released.

Why auto release is required.

What is the good of this auto release, as C + +, the application, their own free, completely controllable not good, this auto relase completely uncontrollable, you do not know when it will be the real releases. I understand it has a role to be able to do each function on its own application of the object of responsibility, their own application, the release of their own, the function of the caller does not need to care about its internal application object management. In the following example, the FUNC1 caller does not need to care about the release of obj.
ClassA *func1 ()
{
ClassA *obj = [[[ClassA alloc]init]autorelease];
return obj;
}

(1) In the iphone project, you will see a default Autorelease pool, the program is created at the beginning, the program exits when the destruction, according to the understanding of autorelease, is not all autorelease The objects in the pool are released when the program exits, which is different from the memory leak.

The answer is that for each runloop, the system implicitly creates a autorelease pool so that all the release pool forms a stack structure like callstack, at the end of each runloop, The Autorelease pool at the top of the current stack is destroyed so that each object in the pool is release.

Then what is a runloop? A UI event, Timer call, and delegate call, will be a new runloop. Examples are as follows:


nsstring* Globalobject;
-(void) applicationdidfinishlaunching: (uiapplication *) application
{
Globalobject = [[NSString alloc] initwithformat:@ "Test"];
NSLog (@ "Retain count after Create:%d", [Globalobject Retaincount]); Output 1.
[Globalobject retain];
NSLog (@ "Retain count after Retain:%d", [Globalobject Retaincount]); Output 2.
}
-(void) Applicationwillterminate: (uiapplication *) application
{
NSLog (@ "Retain count after button click Runloop finished:%d", [Globalobject Retaincount]);
Output 1. Button Click Loop finished, it ' s autorelease Pool released, Globalobject get released once.
}
-(Ibaction) onbuttonclicked
{
[Globalobject Autorelease];
NSLog (@ "Retain count after Autorelease:%d", [Globalobject Retaincount]);
Output 2. Autorelease is called and Globalobject is added as the current autoreleaepool.
}

2, want to understand Runloop can see this explanation (Source: http://www.cnblogs.com/scorpiozj/archive/2011/05/26/2058167.html)

Run Loop

Learning process, will threading PG in the run loops translated, the right to be as a note. The original see Run Loops.

20110526

Reprint Please specify, thank you.

http://www.cnblogs.com/scorpiozj/

Run loops is the infrastructure part of the thread. A run loop is an event-handling loop that is used to continuously provision work and handle input events. The purpose of using Run loop is to make your thread work when there is work and hibernate when there is no.

The management of run loop is not entirely automatic. You still have to design your thread code to start the run loop and respond correctly to input events when appropriate. Both cocoa and corefundation provide the run loop object to facilitate the configuration and management of the thread's run loop. The program you create does not need to be displayed to create the run loop; each thread, including the main thread of the program, has the corresponding run loop object. However, the secondary threads that you create yourself need to run the run loop manually. In carbon and cocoa programs, when a program starts, the main thread creates itself and runs the run loop.

The next section will detail the run loop and how to manage the run loop for your program. Refer to the SDK documentation for the run Loop object.

Parsing the Run Loop

Run loop, as the name suggests, is a loop where your thread starts and runs an event handler to respond to an input event. Your code should have a control statement that implements the loop part, in other words, a while or a for statement. In the run loop, use the Run Loop object to run event-handling code: Respond to received events and start a handler that has already been installed.

There are two different sources of input events handled by the Run loop: input source and timer source. The input source delivers asynchronous messages, usually from other threads or programs. The timing source transmits the synchronization message at a specific time or at a certain time interval. The processing of both provenances uses a specific processing path of the program.

Figure 1-1 shows the structure of the run loop and the various input sources. The input source passes an asynchronous message to the appropriate handler and calls the Rununtildate: Method exit. The timer source passes the message directly to the handler, but does not exit the run loop.

Figure 1-1 Run loop structure and several sources

In addition to processing input sources, the run loop generates notification about the run loop behavior. Registered Run-loop observers can receive these notification and do the appropriate processing. You can use the core Foundation to register the Run-loop viewer on your thread.

The following is an introduction to the composition of the run loop, and its mode of operation. It also refers to sending different notification at different times in the handler.

Run Loop Modes

The Run loop mode is a collection of all the input sources and timing sources to be monitored and the registered observers to notify. Every time run loop runs, it specifies in which mode it will run. Later, only the corresponding sources are monitored and allowed to receive the messages they deliver. (Similarly, only the corresponding observer will receive notification). The source associated with the other schema will run only if the run loop is running in its mode, otherwise it is in a paused state.

The pattern is usually determined by specifying a name in the code. The Cocoa and core Foundation define the default and a series of commonly used patterns, which are identified by strings. Of course you can also specify that the string is derived from the definition pattern. Although you can assign any name to the pattern, all schema content is the same. You must add input sources, timers, or run loop observers to the pattern you define.

Specifying a pattern allows the run loop to focus on only the source of interest at a certain stage. Most of the time, run loop is the default mode that runs in the system definition. However, the modal panel (modal panel) can be run in modal mode. In this mode, only the source associated with the modal panel can pass messages to the thread. For a secondary thread, you can use a custom pattern to handle time-first actions, that is, a source delivery message with a lower-priority mask.

Note: The pattern distinguishes between the source of the event and not the type of event. For example, you may not use the mode to select only the handle of mouse clicks or keyboard events. You can use the mode listening port to pause the timer or other processing of the source or run loop viewer as long as they are in the current mode of listening.

Table 1-1 lists the predefined patterns for cocoa and core Foundation.

Table 1-1

Input source

The input source sends an asynchronous message to the thread. The source of the message depends on the type of input source: The port based input source and the custom input source. Port based source listener corresponding to the port, while the custom input source is concerned with the custom message. As for Run loop, it doesn't care about the type of input source. The system will implement two provenances for you to use. The difference between the two types of input sources is how they are displayed: The Port-based source is automatically sent by the kernel, whereas customizations need to be sent manually from another thread.

When you create an input source, you need to assign it to one or more patterns in the run loop. The pattern only affects the source of the listener in a particular event. In most cases, the run loop runs in the default mode, but you can also make it run in custom mode. If a source is not being monitored in the current mode, any messages it generates will be delivered only if the run loop is running in its associated mode.

These types of input sources are discussed below.

http://www.cnblogs.com/scorpiozj/

Port-based Sources:

The Cocoa and core Foundation provide intrinsic support for port-based sources created using port-related objects and functions. You never need to create an input source directly in cocoa. You simply create the Port object and use the Nsport method to add the Port object to the run loop. The Port object handles creating and configuring the input source.

In Core Foundation, you have to manually create ports and sources, and you can use port types (cfmachportref,cfmessageportref,cfsocketref) to create them.

For more examples, configure a port based source.

Custom input Source:

In a core foundation program, you must use a CFRUNLOOPSOURCEREF type-related function to create a custom input source, and then use a callback function to configure the input source. The Core fundation invokes the callback function at the appropriate time, handling input events, and cleaning up the source.

In addition to defining how messages are processed, you must also define the message-passing mechanism for the source-it runs in a separate process and is responsible for passing data to the source and notifying the source to process the data. The message delivery mechanism is defined by you, but it is better not to be too complicated.

For an example of creating a custom input source, see Defining a custom input source. For information about customizing input sources see Cfrunloopsource.

Cocoa Perform Selector Sources:

In addition to port based sources, cocoa provides input sources that can perform functions (perform selector) on any thread. As with port based sources, perform selector requests are serialized on the target thread, slowing down many of the synchronization problems that are easily caused on a single thread. Unlike a port based source, the perform selector automatically clears the run loop when it finishes executing.

When perform selector is executed in another thread, the target thread must have a run loop in the activity. For the threads you create, this means that the thread is waiting until you show the start of the run loop. However, because the main thread starts the run loop itself, you will encounter a problem with the thread invocation when the program calls Applicationdidfinishlaunching:. Because the run loop handles all permutations of perform selector calls through each loop, the perform selector is processed from time to time through each iteration of the loop.

Table 1-2 lists the perform selector that nsobject can use on other threads. Since these methods are defined in NSObject, you can use all threads including POSIX as long as you have access to OBJC objects. Note that these methods do not actually create a new thread to run perform selector.

Table 1-2

Timing Source

A timed source delivers messages synchronously at a preset point in time. A method by which a thread notifies itself to do something when the timer is used. For example, a search control can use a timer to start a search once a user has entered more than a certain amount of time. This allows the user to have enough time to enter keywords to search for.

Although timers are related to time, they are not real-time. As with the input source, the timer is also associated with the run loop's operating mode. If the timer's mode is not monitored by the run loop, the timer will not start until the run loop is in the appropriate mode. Similarly, if the timer starts when the run loop handles an event, the timer waits until the next run loop starts the appropriate handler. If the run loop is no longer running, the timer will never start.

You can choose whether the timer works once or regularly. If you work regularly, the timer will start automatically based on scheduled time rather than actual time. For example, the timer starts at a certain time and sets 5 seconds to repeat, and the timer starts 5 seconds after that particular time, even when the timer is delayed at that particular time. If the timer is delayed to the next set of more than 5 seconds, the timer will only start once in these time periods, after which normal operation. (Assuming the timer 1,5,9 in time ...) Run, if the initial delay to 7 before starting, it is still from 9, 13, ... Start).

RUN Loop Observer

The source is a synchronous or asynchronous delivery message, while the run Loop observer starts at a specific time while running the run loop. You can use the Run Loop observer to prepare for a particular event or a thread that goes into hibernation. You can associate an observer with the following events: The Run Loop portal run loop is about to start a timed run loop that will process the input source run loop to wake up the Hibernate run loop and terminate the run loop before the wake event is performed

You can add observers to the cocoa and carbon programs, but you can only use core fundation if you want to define the observer. Use the cfrunloopobserverred type to create an observer instance that tracks your custom callback functions and other areas of interest to you.

Similar to timers, observers can be used only once or in a loop. If you use it once, it will remove the run loop at the end, and the Loop observer will not. You need to make an observer is once/multiple use.

Run loop Order of messages

Each time you start, run loop automatically processes the previously unhandled message and notifies the observer. The exact order, as follows: Notifies the Observer that the run loop starts notifying the observer of any impending timer notification to the observer any non-port based source is about to start and start any prepared non-port based source if the port-based source is ready and waiting, start immediately and proceed to step 9. Notifies the Observer that the thread goes into hibernation and threads in hibernation until any of the following events occur an event arrives at the port based source timer startup Set the end time of the run loop the run Loop Wakeup notifies the observer that the thread will be awakened. Handle unhandled events If the user-defined timer starts, handle timed events and restart the run loop. Go to step 2 if the input source is started, pass the corresponding message run loop wakes up but does not terminate, reboot. Enter Step 2 to notify the Observer that the run loop is over.

(Label should be continuous, do not know how to change)

Because the observer's message is passed before the corresponding event occurs, there may be an error between the two. If you need precise time control, you can use hibernation and wake-up notifications to proofread the actual events that occur.

Because timers and other recurring events are started after the run loop is running, the Undo run loop also terminates message delivery. A typical example is mouse path tracking. Because your code gets the message directly rather than through the program, it does not start at the actual time and requires mouse tracking to end and give control to the program.

Use the run Loop object to wake the run loop. Other messages can also wake the run loop. For example, adding a new non-port based source to the run loop allows the input source to be executed immediately instead of waiting for other events to occur.

When to use the run Loop

Http://www.cnblogs.com/scorpiozj/archive/2011/05/26/2058167.html

You only need to run the run loop when you create a secondary thread for your program. The run loop is a critical part of the program's main thread. The cocoa and carbon programs provide code that runs the main thread run loop and also automatically runs the run loop. The Run method in the iOS program uiapplication starts the run loop when the program starts normally. The same part of the work is performed by Runapplicationeventloop in the carbon process. If you use a program created by the template provided by Xcode, you will never have to start the run loop yourself.

And for the secondary thread, you need to decide if you need to run the loop. If you need to run the loop, you are responsible for configuring the run loop and starting it. You don't have to start the run loop under any circumstances. For example, if you use a thread to handle a predefined, time-consuming task, you can start the run loop without the need to do so. The Run loop is only needed when you want to interact with threads, such as the following: Using a port or custom input source and other thread traffic using any performselector in the timer cocoa to enable threads to perform recurring tasks

If you decide to use the run loop in your program, both configuration and startup need to be done by yourself. As with all threads programming, you need to plan when to exit the thread. Ending a thread before exiting is often better than being forced to close a good choice. Detailed configuration and information to launch the run loop are shown using the Run Loop object.

Using the Run Loop object

The Run Loop object provides an interface for adding input sources, timers and observers, and starting the run loop. Each thread has a unique run loop object associated with it. In cocoa, a Nsrunloop object, and a pointer to the CFRUNLOOPREF type in carbon or BSD programs.

Get the Run Loop object

Get the current thread's run loop: cocoa: Using the Nsrunloop Currentrunloop class method to use the Cfrunloopgetcurrent function

Although Cfrunloopref types and Nsrunloop objects are not exactly equivalent, you can get cfrunloopref types from Nsrunloop objects. You can use the Nsrunloop Getcfrunloop method to return the Cfrunloopref type to the core fundation. Because both point to the same run loop, you can use any replacement.

Configure Run Loop

Before the secondary thread starts the run loop, you must add at least one type of source. Because if the run loop has no source to monitor, it will exit immediately upon your launch.

Alternatively, you can add the run loop observer to monitor the different stages of execution of the run loop. First you can create the Cfrunloopobserverref type and use Cfrunloopaddobserver to add it to the gold run loop. Note Even the cocoa program, the run loop Observer needs to be created by the core Foundation function.

The following code 3-1 implements the Add observer to the run loop, which simply establishes an observer to monitor all activities of the run loop and prints out the activities of the run loop. Creating a Run Loop Observer

If the thread is running an event long, it is a good idea to add an input source to the run loop to receive messages. Although you can use the timer, the timer will also exit when it becomes invalid when it is started. Although the timer can loop to make the run loop run for a relatively long time, it also causes a recurring wake-up thread. Instead, the input source waits for an event to occur, and the thread wakes up from hibernation only when the event occurs.

Start Run loop

The run loop only has meaning for the secondary thread of the program, and a class of sources must be added. If not, it will exit after startup. There are several ways to start, such as: unconditional preset time-specific patterns

Unconditional access to the run loop is the simplest choice, but it is least advocated. Because it will keep your thread in a permanent run loop, you will have little control over the run loop itself. You can add or remove sources, timers, but only by killing the process to exit the run loop. And such a run loop has no way to run in custom mode.

It is a good choice to run the run loop with a preset time so that the run loop starts when an event occurs or a preset event expires. If the event occurs, the message is passed to the appropriate handler and the run loop exits. You can restart the run loop to handle the next event. If the time expires, you can simply reboot the run loop or use the timer to do any other work. **

Also, it is a good choice to run the run loop in a specific mode. Patterns and preset times are not mutually exclusive, and they can exist at the same time. The restriction of the mode to the source is described in detail in the Run Loop mode section.

The Listing3-2 code describes the entire structure of the thread. The key to the code is to illustrate the basic structure of the run loop. If necessary, you can add your own input source or timer, and then repeat the start run loop. Every time the run loop returns, you check to see if there is a condition that causes the thread to exit. The core foundation run Loop program is used in the code to check the return result to determine whether to exit. If the cocoa program does not need to care about the return value, you can also run the run loop using the Nsrunloop method (see listing3-14 code) Listing 3-2 Running a run loop

Because the run loop can be started iteratively, that is, you can start the run loop using Cfrunlooprun,cfrunloopruninmode or either Nsrunloop method. In doing so, you can use any mode to start the run loop of the iteration, including the pattern used by the outer run loop.

Exit Run Loop

Before the run loop handles an event, there are two ways to exit it: Set a time-out limit to notify the run loop to stop

If you can configure it, using the first method is a good choice. This allows the run loop to complete all normal operations, including sending a message to the run loop Observer and then exiting.

Using Cfrunloopstop to stop the run loop has a similar effect. The Run loop also sends out all unsent messages before exiting. The difference with setting time is that you can stop the run loop in any case.

Although removing the input sources and timers from the run loop can also cause the run loop to exit, this is not a reliable way to exit the run loop. Some system programs add input sources to handle the required events. And your code doesn't necessarily take that into account, so there's no way to remove it from the system program, so you can't quit the run loop.

Thread-Safe and run loop objects

The security of a thread depends on which API you use to manipulate the run loop. Functions in the Core Foundation are usually thread-safe and can be invoked by any thread. However, if you change the configuration of the run loop and need to do something, you might want to do it on the run loop. If possible, this is a good habit.

As for cocoa, nsrunloop is not inherently thread-safe like the core Foundation. You should only change the run loop while the run loop is online. If you add a yuan or timer to the run loop that belongs to another thread, the program crashes or an unexpected error occurs.

Configuration of the Run loop source

The following example illustrates the use of cocoa and core Foundation to create different types of input sources.

Define a custom input source

Follow these steps to create a custom input source: the information to be processed by the input source to enable interested customers to know how the scheduler that interacts with the input source handles the program that the client sends the request to invalidate the input source cancellation program

Because you create your own source to process messages, the actual configuration is designed to be flexible enough. scheduling, processing, and canceling programs are the key programs you'll always need to create a custom input source. However, most of the other behaviors of the input source are handled by other programs. For example, the mechanism by which you decide to transfer data to the input source, as well as the communication mechanism of the input source and other threads.

Figure 3-2 illustrates the configuration of the custom input source. In this example, the main thread of the program holds the input source, the command buffer required by the input source, and the reference to the run loop where the input source resides. When the main thread has a task and needs to be distributed to the target threads, the main thread sends commands and necessary information to the command buffer so that the active thread can begin to perform the task. (because both the main thread and the input source are required to access the command buffer, their actions should be aware of synchronization.) Once the command is routed, the main thread notifies the input source and wakes the active thread's run loop. Once the wake command is received, the run loop invokes the processing part of the input source, which executes the corresponding command in the command buffer.

Figure 3-2

The key code for the following illustration is explained below.

Define input source

Defining an input source requires the core foundation to be used to configure the run loop source and add it to the run loop. The basic function is the C function, of course, you can also use OBJC or C + + to encapsulate the operation.

The input source in Figure 3-2 uses the OBJC object to manage the command buffer and run loop. Listing3-3 describes the definition of this object: The Runloopsource object manages the command buffer to receive messages from other threads; The Runloopcontext object is one for passing Runloopsource objects and run Loop refers to a container for the main thread of the program. Listing 3-3 The custom input source object definition

Although the data definition for the input source is OBJC code, adding the source to the run loop requires C's callback function. The above functions are called when they are added, like listing3-4. Because this input source has only one client (that is, the main thread), it uses the dispatch function to send the registration information to the program's agent (delegate). When the agent needs to communicate with the input source, it can be implemented using the Runloopcontext object.

Related Article

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.