やっと分かった。

スレッドセーフになってないようです。
ThreadsDataSource#tableView: ...でlocalThreadsにアクセスしている途中に
別のスレッドによりThreadsList#setLocalThreadsを実行し、localThreadsがreleaseされてます。

これはnewThreadsとlocalThreadsをThreadsListとThreadsDataSourceの2つのインスタンスで共有するために発生するものと思います。
ThreadsListでnewThreadsとlocalThreadsを操作する場合はlockが行われているのですが
ThreadsDataSourceのほうではlockを取得していません。よってThreadsListがlockを取得している間もThreadsDataSourceから共有されたnewThreadsとlocalThreadsにアクセスできてしまいます。

解決方法:
まずThreadsListに
- (void)lock {
[newThreadsLock lock];
[localThreadsLock lock];
}
- (void)unlock {
[newThreadsLock unlock];
[localThreadsLock unlock];
}
を追加し、ThreadsDataSourceのnewThreads、localThreadsにアクセスするメソッドで[threadsList lock]、[threadsList unlock]を行う。

これをやってみたところ即デッドロックするので、
ThreadsListのinitWithBoardName:のロックの初期化のところを
localThreadsLock = [[NSRecursiveLock allocWithZone:zone] init];
newThreadsLock = [[NSRecursiveLock allocWithZone:zone] init];
に変更します。
とりあえず落ちなくなるとは思いますが、パフォーマンスは落ちますね、、、。