The following documents are collected at the beginning of development.
Multi-thread 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 (mytaskmethod :) object: Data];
// Add the created operation to the local device Program (The method will be executed immediately after being 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 ){
Operationqueue = [[nsoperationqueue alloc] init]; // initialize the operation queue
[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];
// As Alan often said, we are a good citizen of the program and need to release the memory!
[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.
//////////////////////////////////////// //////////////////////////////////////// ///////////////////
1. Add a loading screen to the main thread ......
2 {
3 [Window addsubview: view_loading];
4 [nsthread detachnewthreadselector: @ selector (init_backup :) totarget: Self withobject: Nil];
5}
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.
7-(void) init_backup :( ID) sender
8 {
9 NSAID utoreleasepool * Pool = [[NSAID utoreleasepool alloc] init];
10
11 //...
12 INT I = status;
13 [self defined mselecw.mainthread: @ selector (show_loading :) withobject: [nsnumber numberwithint: I] waituntil done: No];
14
15 [view_loading removefromsuperview];
16 [Window addsubview: tabcontroller_main.view];
17 [pool release];
18}
//////////////////////////////////////// ///////////////
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 <uikit/uikit. h>
@ Interface sellticketsappdelegate: nsobject <uiapplicationdelegate> {
Int tickets;
Int count;
Nsthread * ticketsthreadone;
Nsthread * ticketsthreadtwo;
Nscondition * ticketscondition;
Uiwindow * window;
}
@ Property (nonatomic, retain) iboutlet uiwindow * window;
@ End
Then add the following Code :
// Sellticketsappdelegate. m
// Selltickets
//
// Created by Sun dfsun2009 on 09-11-10.
// Copyright _ mycompanyname _ 2009. All rights reserved.
//
# 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];
}
@ End
Bytes -------------------------------------------------------------------------------------
// Define
# Import <uikit/uikit. h>
@ Interface threadsyncsampleviewcontroller: uiviewcontroller {
Int _ threadcount;
Nscondition * _ mycondition;
}
@ End
// The implementation file is as follows:
# Import "threadsyncsampleviewcontroller. H"
@ Implementation threadsyncsampleviewcontroller
/*
// The designated initializer. Override to perform setup that is required before the view is loaded.
-(ID) initwithnibname :( nsstring *) nibnameornil bundle :( nsbundle *) nibbundleornil {
If (Self = [Super initwithnibname: nibnameornil Bundle: nibbundleornil]) {
// Custom Initialization
}
Return self;
}
*/
/*
// Implement loadview to create a view hierarchy programmatically, without using a nib.
-(Void) loadview {
}
*/
// Implement viewdidload to do additional setup after loading the view, typically from a nib.
-(Void) viewdidload {
[Super viewdidload];
//
// _ Mycondition = nil;
//
_ Mycondition = [[nscondition alloc] init];
//
Nstimer * timer = [nstimer scheduledtimerwithtimeinterval: 30
Target: Self
Selector: @ selector (threadtester)
Userinfo: Nil
Repeats: Yes];
[Timer fire];
}
-(void) threadtester {
[_ mycondition lock];
_ threadcount =-2;
// if there are n threads to wait, set them to-n
[_ mycondition unlock];
//
nslog (@ "");
nslog (@ "timer");
[nsthread detachnewthreadselector: @ selector (threadone) totarget: self withobject: Nil];
[nsthread detachnewthreadselector: @ selector (threadtwo) totarget: Self withobject: Nil];
[nsthread attributes: @ selector (threadthree) totarget: self withobject: Nil];
return;
}
-(void) threadone {
nslog (@ "@ in thread 111111 start. ");
[_ mycondition lock];
int n = rand () % 5 + 1;
nslog (@ "@ thread 111111 will sleep % d seconds, now _ threadcount is: % d", N, _ threadcount );
sleep (n);
// [nsthread sleepfortimeinterval: N];
_ threadcount ++;
nslog (@ "@ thread 111111 has sleep % d seconds, now _ threadcount is: % d", N, _ threadcount );
[_ mycondition signal];
nslog (@ "@ thread 1111111 has signaled, now _ threadcount is: % d", _ threadcount );
[_ mycondition unlock];
nslog (@ "@ in thread one complete. ");
[nsthread exit];
return;
}
-(void) threadtwo {
nslog (@ "### in thread 2222222 start. ");
[_ mycondition lock];
int n = rand () % 5 + 1;
nslog (@ "### thread 2222222 will sleep % d seconds, now _ threadcount is: % d", N, _ threadcount );
sleep (n);
// [nsthread sleepfortimeinterval: N];
_ threadcount ++;
nslog (@ "### thread 2222222 has sleep % d seconds, now _ threadcount is: % d", N, _ threadcount );
[_ mycondition signal];
nslog (@ "### thread 2222222 has signaled, now _ threadcount is: % d", _ threadcount );
[_ mycondition unlock];
// _ threadcount ++;
nslog (@ "### in thread 2222222 complete. ");
[nsthread exit];
return;
}
-(Void) threadthree {
Nslog (@ "<in thread 333333 start .");
[_ Mycondition lock];
While (_ threadcount <0 ){
[_ Mycondition Wait];
}
Nslog (@ "<in thread 333333, _ threadcount now is % d, will start work.", _ threadcount );
[_ Mycondition unlock];
Nslog (@ "<in thread 333333 complete .");
[Nsthread exit];
Return;
}
/*
// Override to allow orientations other than the default portrait orientation.
-(Bool) shouldautorotatetointerfaceorientation :( uiinterfaceorientation) interfaceorientation {
// Return YES For supported orientations
Return (interfaceorientation = uiinterfaceorientationportrait );
}
*/
-(Void) didreceivememorywarning {
// Releases the view if it doesn't have a superview.
[Super didreceivememorywarning];
// Release any cached data, images, etc that aren't in use.
}
-(Void) viewdidunload {
// Release any retained subviews of the main view.
// E.g. Self. myoutlet = nil;
}
-(Void) dealloc {
[_ Mycondition release];
[Super dealloc];
}
@ End