iOS: performSelectorOnMainThread waitUntilDone 参数详解

来源:互联网 发布:ticwatch软件下载 编辑:程序博客网 时间:2024/04/29 20:57

http://www.41443.com/HTML/iphone/20150126/300050.html

iOS 中performSelectorOnMainThread  参数 waitUntilDone 很多说这个参数在主线程无效,这样的说法是错误的,当这个参数为YES,时表示当前runloop循环中的时间马上响应这个事件,如果为NO则runloop会将这个事件加入runloop队列在合适的时间执行这个事件。

可以通过block的同步和异步执行方式来观察这个参数;具体代码如下:

可以看出为YES时马上执行,为NO时先加入主线程的runloop事件循环里面,等待runloop来调度执行。

- (void)viewDidLoad {    [super viewDidLoad];//    NSTextAttachment        _label = [[UILabel alloc] initWithFrame:CGRectMake(100, 200, 200, 50)];        [self.view addSubview:_label];        NSTextAttachment *attach = [[NSTextAttachment alloc] init];        attach.image = [UIImage imageNamed:@"d_chanzui"];        attach.bounds = CGRectMake(0, -3, 15, 15);        NSMutableAttributedString *emotionStr = [[NSAttributedString attributedStringWithAttachment:attach] mutableCopy];        NSAttributedString *attributeStr = [[NSAttributedString alloc] initWithString:@"jjjjj"];        [emotionStr appendAttributedString:attributeStr];        _label.attributedText = emotionStr;        NSMutableDictionary *textAttrs = [NSMutableDictionary dictionary];    textAttrs[NSForegroundColorAttributeName] = [UIColor redColor];    textAttrs[NSFontAttributeName] = [UIFont systemFontOfSize:40];        [emotionStr addAttributes:textAttrs range:NSMakeRange(0, emotionStr.length)];        _label.attributedText = emotionStr;        NSAttributedString *dictString = [[NSAttributedString alloc] initWithString:@"sdfsdf" attributes:textAttrs];        _label.attributedText = dictString;    //    _label.attributedText = textAttrs;        array = @[@"123", @"32", @"56", @"78"];        array = [array sortedArrayUsingComparator:^NSComparisonResult(NSString *str1, NSString *str2) {        //        {NSOrderedAscending = -1L, NSOrderedSame, NSOrderedDescending};                BOOL isBig = str1.integerValue < str2.integerValue;                if (isBig) {                        return NSOrderedDescending;        }                return NSOrderedAscending; //NSOrderedAscending NSOrderedDescending            }];        NSLog(@"the array is %@", array);////    array sor            //同步执行的block    [self blockTest:^(int var) {                for (int i = 0; i < 9; i++) {            NSLog(@"b");        }                NSLog(@"var is %d", var);            }];        NSLog(@"sdfsdf");        //    //异步执行的block//    [self asyncBlockTest:^(int var) {//        //        for (int i = 0; i < 90; i++) {//            NSLog(@"b");//        }//        //        NSLog(@"async var is %d", var);//        //    }];//    //    NSLog(@"sdfsdf");    }//typedef <#returnType#>(^<#name#>)(<#arguments#>);- (void)blockTest:( void (^)(int) )myBlock{        //同步执行//    myBlock(12);        //异步执行的block//    dispatch_async(dispatch_get_main_queue(), ^{//        myBlock(12);//    });        [self performSelectorOnMainThread:@selector(asyncBlockAction:) withObject:myBlock waitUntilDone:NO];    }- (void)asyncBlockAction :( void (^)(int) )myBlock {        myBlock(122);}


- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait
performSelectorOnMainThread:withObject:waitUntilDone:
基于默认模式调用主线程中接收器的方法
Invokes a method of the receiver on the main thread using the default mode.

参数 Parameters
aSelector
一个选择器, 指定要调用的方法。该方法不应该有明确的返回值并且最多只有一个id类型的参数,或者没有参数。
A selector that identifies the method to invoke. The method should not have a significant return value and should take a single argument of type id, or no arguments.

arg
需要传递给调用方法的参数. 如果没有需要的参数,传入nil
The argument to pass to the method when it is invoked. Pass nil if the method does not take an argument.

wait
一个布尔值,指定是否阻塞当前线程直到指定选择器在主线程中执行完毕。选择YES会阻塞这个线程;选择NO,本方法会立刻返回。
A Boolean that specifies whether the current thread blocks until after the specified selector is performed on the receiver on the main thread. Specify YES to block this thread; otherwise, specify NO to have this method return immediately.
如果当前线程也是主线程,选择YES,消息会立即派发,处理。
If the current thread is also the main thread, and you specify YES for this parameter, the message is delivered and processed immediately.

讨论 Discussion

你可以使用本方法向主线程发送消息. 主线程包含应用程序的主循环(这是NSApplication接收事件的地方). 在这种情况下, 消息相当于是你想要在线程上执行的当前对象的方法.
You can use this method to deliver messages to the main thread of your application. The main thread encompasses the application’s main run loop, and is where the NSApplication object receives events. The message in this case is a method of the current object that you want to execute on the thread.

本方法使用Common模式将消息加入到主线程运行循环(run loop)队列, 即 与NSRunLoopCommonModes常数相关的模式。作为其正常运行循环处理的一部分,主线程从队列中取出消息(假设它是在Common模式中运行)并调用所需的方法。在同一个线程多次调用此方法会导致相应的选择进行排队,再按相同的顺序取出执行。
This method queues the message on the run loop of the main thread using the common run loop modes—that is, the modes associated with the NSRunLoopCommonModes constant. As part of its normal run loop processing, the main thread dequeues the message (assuming it is running in one of the common run loop modes) and invokes the desired method. Multiple calls to this method from the same thread cause the corresponding selectors to be queued and performed in the same same order in which the calls were made.

你不能取消由本方法加入队列的消息. 如果你想取消当前线程的一条消息, 必须使用
performSelector:withObject:afterDelay: 或 
performSelector:withObject:afterDelay:inModes: 方法.
You cannot cancel messages queued using this method. If you want the option of canceling a message on the current thread, you must use either the 
performSelector:withObject:afterDelay: or 
performSelector:withObject:afterDelay:inModes: method.

特别注意事项
Special Considerations
本方法在runloop中注册当前上下文, 并且依赖于runloop定期运行以保证正确执行. (?????此处翻译不出, 请大家帮助)。如果你在运行一个调度队列时需要这种类型的功能, 你应该使用dispatch_after和相关的方法来得到你想要的行为。
This method registers with the runloop of its current context, and depends on that runloop being run on a regular basis to perform correctly. One common context where you might call this method and end up registering with a runloop that is not automatically run on a regular basis is when being invoked by a dispatch queue. If you need this type of functionality when running on a dispatch queue, you should use dispatch_after and related methods to get the behavior you want.

(责任编辑:幽灵学院)

0 0