【问题标题】:Detect end of performSelectorInBackground:withObject:检测 performSelectorInBackground:withObject 的结束:
【发布时间】:2011-03-23 14:31:59
【问题描述】:

我的 iOS 应用中有一个异步服务器请求:

[self performSelectorInBackground:@selector(doSomething) withObject:nil];

如何检测到此操作的结束?

【问题讨论】:

    标签: iphone multithreading ios detect nsthread


    【解决方案1】:

    在 doSomething 方法的末尾调用?!

    - (void)doSomething {
        // Thread starts here
    
        // Do something
    
        // Thread ends here
        [self performSelectorOnMainThread:@selector(doSomethingDone) withObject:nil waitUntilDone:NO];
    }
    

    【讨论】:

    • 这是规范的方式,尽管最近我一直认为,如果你明确编码到后台线程中,你可能做错了什么(或者至少是“艰难的方式” )。大多数可能阻塞主线程的东西都有一个异步方法,带有回调块或委托方法来处理结果。
    【解决方案2】:

    如果您只想知道它何时完成(并且不想传回太多数据 - 我会推荐一个代表),您可以简单地向通知中心发布通知。

    [[NSNotificationCenter defaultCenter] postNotificationName:kYourFinishedNotificationName object:nil];
    

    在您的视图控制器 viewDidLoad 方法中添加:

    [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(yourNotificationListenerMethod:)
                                                     name:kYourFinishedNotificationName
                                                   object:nil];
    

    在dealloc中,添加:

    [[NSNotificationCenter defaultCenter] removeObserver:self];
    

    【讨论】:

      【解决方案3】:

      您可能希望在 doSomething 选择器完成后将其返回。 performSelectorInBackground 上发生的事情是 API 内部的,如果您想要更多控制权,您可能需要使用 performSelector:onThread:withObject:waitUntilDone: 并定期检查传递的线程上的 isFinished。我相信你更关心 doSomething 完成而不是实际线程,所以只需从那里发回。

      【讨论】:

        【解决方案4】:

        我创建了一个通用的后台处理程序来解决这个问题。只有第一种方法是公开的,所以它可以在整个过程中使用。请注意,所有参数都是必需的。

        +(void) Run: (SEL)sel inBackground: (id)target withState: (id)state withCompletion: (void(^)(id state))completionHandler       // public
        {
            [(id)self performSelectorInBackground: @selector(RunSelector:) withObject: @[target, NSStringFromSelector(sel), state, completionHandler]];
        }
        
        +(void) RunSelector: (NSArray*)args
        {
            id target = [args objectAtIndex: 0];
            SEL sel = NSSelectorFromString([args objectAtIndex: 1]);
            id state = [args objectAtIndex: 2];
            void (^completionHandler)(id state) = [args objectAtIndex: 3];
            [target performSelector: sel withObject: state];
            [(id)self performSelectorOnMainThread: @selector(RunCompletion:) withObject: @[completionHandler, state] waitUntilDone: true];
        }
        
        +(void) RunCompletion: (NSArray*)args
        {
            void (^completionHandler)(id state) = [args objectAtIndex: 0];
            id state = [args objectAtIndex: 1];
            completionHandler(state);
        }
        

        这是一个如何调用的示例:

        NSMutableDictionary* dic = [[NSMutableDictionary alloc] init];
        __block BOOL done = false;
        [Utility Run: @selector(RunSomething:) inBackground: self withState: dic withCompletion:^(id state) {
                done = true;
            }];
        

        【讨论】:

          猜你喜欢
          • 2012-05-06
          • 1970-01-01
          • 1970-01-01
          • 2014-08-14
          • 1970-01-01
          • 2023-03-29
          • 1970-01-01
          • 1970-01-01
          • 2014-11-27
          相关资源
          最近更新 更多