使用performSelectorInBackground的风险?

Dan*_*ark 3 multithreading objective-c ios

我一直在使用ObjectiveResource(iOS-> Rails桥)进行一些测试.事情似乎有效,但图书馆是同步的(或许不是,但支持它的邮件列表是一团糟).

我想知道在一个performSelectorInBackground小测试中运行所有调用的陷阱是什么 ...它似乎工作得很好,但是很多事情都是错误的.

我注意到的唯一警告是你必须在performSelectorInBackground调用的方法中创建一个自动释放池(然后你应该只调用drain而不是release?).

Cra*_*tis 8

所以你真的遇到任何问题吗?或者你只是期待它们?

除非您尝试从同一后台线程更新UI元素,否则在后台线程上运行不应该给您任何问题.务必将任何与UI相关的活动转发到主线程.例如(伪):

- (void)viewWillAppear:(BOOL)animated {
    [self performSelectorInBackground:@selector(refreshTableView)];
    [super viewWillAppear:animated];
}

- (void)refreshTableView {
    // Where _listOfObjects is used to populate your UITableView
    @synchronized(self) {
        self._listOfObjects = [MyDataType findAllRemote];
    }
    [self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:YES];
}
Run Code Online (Sandbox Code Playgroud)

请注意(如上所述)如果要更改后台线程上任何实例变量的值,则必须同步self以防止任何其他线程(如主线程)在_listOfObjects更新时访问阵列中的对象或设定.(或者你可能"得到"一个不完整的对象.)

我不是百分之百肯定(欢迎评论),但我相信如果你声明_listOfObjects属性atomic,你将不需要担心synchronized块.但是,@property如果不是重新分配属性的值,而是重新分配单个持久化实例,则无论声明如何都需要synchronized块.(例如,从静态NSMutableArray添加/删除对象.)


Chu*_*uck 8

performSelectorInBackground:在幕后使用线程,线程的重点是任何一个代码触及的代码都是竞争条件和其他微妙错误的雷区.这显然意味着在主线程之外向屏幕绘图是禁止的.但是还有很多其他库也不是线程安全的,任何使用它们的代码也都会受到污染.

基本上,线程安全是你必须故意放入代码中的东西,或者它可能不存在.ObjectiveResource没有提出任何要求,所以我已经紧张了.看一下源代码,看起来它主要使用的是基础URL加载机制,即线程安全IIRC.但ObjectiveResource代码本身不是.一目了然,所有类方法都使用静态变量,这意味着如果您performSelectorInBackground:使用它们的代码不止一次,它们都会受到竞争条件的影响.

看起来它们的Github上的1.1分支通过ConnectionManager类明确支持异步.可能更好地使用它(虽然这基本上是没有维护的代码,所以需要注意).