NSObject executes the Selector related method, nsobjectselector
1. Cancel Selector Sources in the current Run Loop
NSObjectInperformSelector:withObject:afterDelay:In the Run Loop of the current threadafterDelayCreate a Timer parameter.inModesParameter method. The Timer runs in the default mode of the current Run Loop, that isNSDefaultRunLoopModeIn the defined mode.
performSelector:withObject:afterDelay:The method looks simple. Here is another helper function, which is static in NSObject.cancelPreviousPerformRequestsWithTargetMethod. 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 usecancelPreviousPerformRequestsWithTargetCancels 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, noteselectorAndobjectThe 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.NSObjectOfperformSelectorInBackground: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 equivalentNSThreadOfdetachNewThreadSelector:toTarget:withObject:Static method, then the aboveNSObjectOfperformSelectorInBackground:withObject:Method call can be replaced:
[NSThread detachNewThreadSelector:@selector(test:) toTarget:self withObject:nil];
Of course, you can also manually createNSThreadThe 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 isNSObjectOfperformSelector:onThread:withObject:waitUntilDone:Method. Because it is in anotherNSThreadSo we need to manually start the Run Loop. First, you mustViewControllerDefine two fields, which areNSThreadAnd 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 threadNSRunLoopOfrunMode: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 lastwaitUntilDoneParameter.YESThe 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];
}