IOS development: multithreading NSThread and NSInvocationOperation
Multi-threaded programming is the best way to prevent the main thread from being congested and increase the running efficiency. The original multi-threaded method has many problems, including thread locking. In Cocoa, Apple provides the NSOperation class and an excellent multi-threaded programming method.
This section describes the subset of NSOperation and NSInvocationOperation of the simple method:
@ Implementation MyCustomClass
-(Void) launchTaskWithData :( id) data
{
// Create an NSInvocationOperation object and initialize it to the method;
// Here, the value after the selector parameter is the Method (function, Method) You want to run in another thread );
// Here, the object value is the data to be passed to the previous method.
NSInvocationOperation * theOp = [[NSInvocationOperation alloc] initWithTarget: self selector: @ selector (myTashMethod :) object: data];
// Add the created Operation "Operation" to the shared queue of the local program (the method will be executed immediately after it is added)
// In more cases, we create an "operation" queue by ourselves.
[[MyAppDelegate implements doperationqueue] addOperation: theOp];
}
// This is the "method" that actually runs in another thread"
-(Void) myTaskMethod :( id) data
{
// Perform the task.
}
@ End
// An NSOperationQueue operation queue is equivalent to a thread manager rather than a thread. Because you can set the number of threads that can run in parallel in this thread manager.
// The following describes how to create and initialize an operation queue:
@ Interface MyViewController: UIViewController {
NSOperationQueue * operationQueue;
// Declare the queue in the header file
}
@ End
@ Implementation MyViewController
-(Id) init
{
Self = [super init];
If (self ){
// Initialize the operation queue
OperationQueue = [[NSOperationQueue alloc] init];
[OperationQueue setMaxConcurrentOperationCount: 1];
// This limits the queue to run only one thread at a time
// This queue is ready for use.
}
Return self;
}
-(Void) dealloc
{
[OperationQueue release];
[Super dealloc];
}
@ End
// After a brief introduction, we can find that this method is very simple. In many cases, multithreading is only used to prevent main thread congestion, and NSInvocationOperation is the simplest multi-threaded programming, which is often used in iPhone programming.
//////////////////////////////////////// /////////////////////
// Add a loading image to the main thread ......
{
[Window addSubview: view_loading];
// Another new thread may need time for background processing. In order to prevent the main program from waiting for a static period of time, the background processing is placed outside the main thread for execution. After execution, notifies the main thread to update data.
[NSThread detachNewThreadSelector: @ selector :( init_backup :) toTarget: self withObject: nil];
}
// You can use javasmselectorohmainthread to update UI elements, such as setting progress bars. Finally, the loading screen is eliminated and loaded into the main View.
-(Void) init_backup :( id) sender
{
NSAID utorelease * pool = [[NSAID utoreleasepool alloc] init];
// The newly created thread requires an automatic release pool to manage the memory applied in the thread
Int I = status;
[Self defined mselecw.mainthread: @ selector :( show_loading :) wiwithObject: [NSNumber numberWithInt: I] waitUntil Done: NO];
[View_loading removeFromSuperview];
[Window addSubview: tabcontroller_main.view];
[Pool release];
}
Multi-thread implementation and thread synchronization using iphone
From the interface definition, we can know that NSThread and most iphone interface objects are the same, there are two ways to initialize:
One method is to use initWithTarget :( id) target selector :( SEL) selector object :( id) argument, but to call the release method of the object to clear the object when the retain count of the object is 0.
The other method uses the so-called convenient method. This convenient interface is detachNewThreadSelector. This method can directly generate a thread and start it, without being responsible for thread cleaning.
# Import
@ Interface SellTicketsAppDelegate: NSObject
{
Int tickets;
Int count;
NSThread * ticketsThreadone;
NSThread * ticketsThreadtwo;
NSCondition * ticketsCondition;
UIWindow * window;
}
@ Property (nonatomic, retain) IBOutlet UIWindow * window;
@ End
// SellTicketsAppDelegate. m
# Import "SellTicketsAppDelegate. h"
@ Implementation SellTicketsAppDelegate
@ Synthesize window;
-(Void) applicationDidFinishLaunching :( UIApplication *) application
{
Tickets = 100;
Count = 0;
// Lock Object
TicketCondition = [[NSCondition alloc] init];
TicketsThreadone = [[NSThread alloc] initWithTarget: self selector: @ selector (run) object: nil];
[TicketsThreadone setName: @ "Thread-1"];
[TicketsThreadone start];
TicketsThreadtwo = [[NSThread alloc] initWithTarget: self selector: @ selector (run) object: nil];
[TicketsThreadtwo setName: @ "Thread-2"];
[TicketsThreadtwo start];
// [NSThread detachNewThreadSelector: @ selector (run) toTarget: self withObject: nil];
// Override point for customization after application launch
[Window makeKeyAndVisible];
}
-(Void) run {
While (TRUE ){
// Lock
[TicketsCondition lock];
If (tickets> 0)
{
[NSThread sleepForTimeInterval: 0.5];
Count = 100-tickets;
NSLog (@ "Current ticket count: % d, sold: % d, thread name: % @", tickets, count, [[NSThread currentThread] name]);
Tickets --;
}
Else
{
Break;
}
[TicketsCondition unlock];
}
-(Void) dealloc {
[TicketsThreadone release];
[TicketsThreadtwo release];
[TicketsCondition release];
[Window release];
[Super dealloc];
}