NSObject executes the Selector related method, nsobjectselector
1. Cancel Selector Sources in the current Run Loop
NSObject
InperformSelector:withObject:afterDelay:
In the Run Loop of the current threadafterDelay
Create a Timer parameter.inModes
Parameter method. The Timer runs in the default mode of the current Run Loop, that isNSDefaultRunLoopMode
In the defined mode.
performSelector:withObject:afterDelay:
The method looks simple. Here is another helper function, which is static in NSObject.cancelPreviousPerformRequestsWithTarget
Method. This method is used to cancel cancellation.performSelector:withObject:afterDelay:
The Selector source created by the method (internally, It is the Timer source of the Run Loop ). Therefore, this method andperformSelector:withObject:afterDelay:
The method is the same, only in the current Run Loop.
We can usecancelPreviousPerformRequestsWithTarget
Cancels all unexecuted objects in the current Run Loop.performSelector:withObject:afterDelay:
The Selector Sources generated by the method is as follows:
-(Void) viewDidLoad
{
[Super viewDidLoad];
[Self defined mselector: @ selector (test :) withObject: nil afterDelay: 1];
[Self defined mselector: @ selector (test :) withObject: @ "mgen" afterDelay: 2];
[NSObject cancelPreviousPerformRequestsWithTarget: self];
}
-(Void) test :( id) obj
{
NSLog (@ "successful call: % @", obj );
}
There will be no output, because both calls are canceled.
UsecancelPreviousPerformRequestsWithTarget:selector:object:
Method, noteselector
Andobject
The parameters must be one-to-one. The following code:
-(Void) viewDidLoad
{
[Super viewDidLoad];
[Self defined mselector: @ selector (test :) withObject: [NSNumber numberWithInt: 26] afterDelay: 1];
[Self defined mselector: @ selector (test :) withObject: [NSNumber numberWithInt: 17] afterDelay: 2];
[Self defined mselector: @ selector (test :) withObject: [NSNumber numberWithInt: 17] afterDelay: 3];
[NSObject cancelPreviousPerformRequestsWithTarget: self selector: @ selector (test :) object: [NSNumber numberWithInt: 17];
}
-(Void) test :( id) obj
{
NSLog (@ "successful call: % @", obj );
}
Only:
Call successful: 26
The other two selectors are canceled.
Returned directory
2. Run Selector in NSThread
This topic is very simple.NSObject
OfperformSelectorInBackground:withObject:
You can use the following code:
- (void)viewDidLoad
{
[super viewDidLoad];
[self threadInfo:@"UI"];
[self performSelectorInBackground:@selector(test:) withObject:nil];
}
- (void)test:(id)obj
{
@autoreleasepool
{
[self threadInfo:@"test"];
}
}
- (void)threadInfo:(NSString*)category
{
NSLog(@"%@ - %@", category, [NSThread currentThread]);
}
Output:
UI - <NSThread: 0x71639e0>{name = (null), num = 1}
test - <NSThread: 0x7176ad0>{name = (null), num = 3}
This method is equivalentNSThread
OfdetachNewThreadSelector:toTarget:withObject:
Static method, then the aboveNSObject
OfperformSelectorInBackground:withObject:
Method call can be replaced:
[NSThread detachNewThreadSelector:@selector(test:) toTarget:self withObject:nil];
Of course, you can also manually createNSThread
The Code is as follows:
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(test:) object:nil];
[thread start];
The output after the two methods are run is similar to the first type.
Returned directory
3. Run Selector in the Run Loop of NSThread.
The required method isNSObject
OfperformSelector:onThread:withObject:waitUntilDone:
Method. Because it is in anotherNSThread
So we need to manually start the Run Loop. First, you mustViewController
Define two fields, which areNSThread
And the flag executed by the Run Loop in the control thread.
@interface ViewController ()
{
NSThread *_thread;
BOOL _isNewThreadAborted;
}
The next step is to execute this thread and manually call it in the threadNSRunLoop
OfrunMode:beforeDate:
Method. Note that if the Run Loop does not have any Source, this method will return immediately, so you need to create a Loop to continuously call the Run LooprunMode:beforeDate:
Method. And tries to end the loop after the Selector execution ends. The final code is as follows:
-(Void) viewDidLoad
{
[Super viewDidLoad];
[Self threadInfo: @ "UI"];
_ IsNewThreadAborted = NO;
_ Thread = [[NSThread alloc] initWithTarget: self selector: @ selector (newThread :) object: nil];
// Start thread
[_ Thread start];
// Execute Selector in the Run Loop of another thread
[Self defined mselector: @ selector (test :) onThread: _ thread withObject: nil waitUntilDone: NO];
}
// Create and start a nsunloop in the new thread
-(Void) newThread :( id) obj
{
@ Autoreleasepool
{
Nsunloop * currentRunLoop = [nsunloop currentRunLoop];
While (! _ IsNewThreadAborted)
{
[CurrentRunLoop runMode: NSDefaultRunLoopMode beforeDate: [NSDate distantFuture];
}
NSLog (@ "thread stopped ");
}
}
// Selector execution
-(Void) test :( id) obj
{
[Self threadInfo: @ "test"];
_ IsNewThreadAborted = YES;
}
-(Void) threadInfo :( NSString *) category
{
NSLog (@ "% @-% @", category, [NSThread currentThread]);
}
Output:
UI-<NSThread: 0x717e7e0> {name = (null), num = 1}
Test-<NSThread: 0x8078a80> {name = (null), num = 3}
Thread stopped
Last noteperformSelector:onThread:withObject:waitUntilDone:
The lastwaitUntilDone
Parameter.YES
The current thread will wait until the Selector completes execution in another thread.
4.Association between UIPinchGestureRecognizer and NSObject Selector
If (recognizer. state = UIGestureRecognizerStateChanged ){
[NSObject cancelPreviousPerformRequestsWithTarget: self selector: @ selector (XXXSetNeedsDisplay) object: recognizer];
// Related methods...
} Else if (recognizer. state = UIGestureRecognizerStateEnded ){
[Self defined mselector: @ selector (XXXSetNeedsDisplay) withObject: recognizer afterDelay: 1.0f];
}