菜鸟教程小白 发表于 2022-12-12 19:52:51

objective-c - 获取例程中的死锁


                                            <p><p>我坚持使用我的第一个 GCD 和第一个核心数据,使用应用程序 =)</p>

<p>两个 View 访问相同的数据(由单个 DAO 处理)。 </p>

<p>如果我等待当前 View 完成加载其内容,则在更改 View 时不会出现问题。 </p>

<p>但是:如果我在一个 Controller 尝试从我的模型中获取数据时更改 View (其基于选项卡的 View ),则新 Controller 会尝试相同的操作,并且线程“冲突”并且我的应用程序会卡住。</p>

<p>卡住发生在我的 DAO 的这行代码中:</p>

<pre><code>    NSArray *results = ;   
</code></pre>

<p><code>reloadAllMonth()</code> 访问我的 DAO 的 fetch 例程</p>

<p>我如何在第一个 Controller 中加载数据:</p>

<pre><code>dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {
                ;

                dispatch_async(dispatch_get_main_queue(), ^(void) {                        
                  ;   
                });
</code></pre>

<p>在第二个 ViewController 中,我做的第一件事是更新我的 DAO,这当然使用(在其他人之下)我之前调用的完全相同的 fetch 例程:</p>

<pre><code>    ;
</code></pre>

<p>到目前为止,我已经尝试了两种方法:</p>

<p><strong>首先</strong>使用 c 信号量:</p>

<pre><code>-(NSArray *)fetchAllMonthExpenses{
    //@return: array of all expenses in month (day &amp; month type)


    NSNumber *monthNumber = ];
      NSEntityDescription *exp = ;
    NSFetchRequest *fetch = [init];
    ;
    ];
    NSError *error = nil;
    sem_wait(&amp;isLoading);
    NSArray *results = ;
    sem_post(&amp;isLoading);
    return results;

}
</code></pre>

<p><strong>秒</strong>使用同步指令</p>

<pre><code>-(NSArray *)fetchAllMonthExpenses{
    //@return: array of all expenses in month (day &amp; month type)


    NSNumber *monthNumber = ];
      NSEntityDescription *exp = ;
    NSFetchRequest *fetch = [init];
    ;
    ];
    NSError *error = nil;
    @synchronized(self.class){
      NSArray *results = ;
      return results;
    }   
}
</code></pre>

<p>遗憾的是这两种方法都不起作用,应用程序卡住了我所做的一切。</p>

<p>所以我的问题是:我做错了什么(正如我第一次使用线程时提到的),我错过了什么,我应该去哪里看?</p>

<p>这已经让我忙了 2 天了,我似乎无法理解它:/</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>一个 <code>NSManagedObjectContext</code> 和其中的所有 <code>NSManagedObjects</code> 都不是线程安全的。</p>

<p>无论您使用什么线程来创建上下文,都需要是 <em>only</em> 线程,您可以在其中执行与该上下文相关的<em>任何事情</em>。即使只是从一个托管对象中读取值也必须<em>在该线程上</em>完成,而不是在任何其他线程上完成。</p>

<p>如果您需要两个线程同时处理同一个数据库,您有两种选择:</p>

<ul>
<li>使用 <code>dispatch_sync()</code> 暂时跳转到另一个线程以对托管对象和/或上下文执行所有读/写操作</li>
</ul>

<p>或者:</p>

<ul>
<li>在另一个线程中为同一个数据库创建第二个 <code>NSManagedObjectContext</code>,并使对这两个上下文所做的任何更改保持同步。</li>
</ul>

<p>第一个选项更容易,但可能会消除线程的大部分好处。第二个选项更难,但可以做到,并且有一个相当不错的 API 可以使不同线程上的两个上下文保持同步。</p>

<p>查看核心数据编程指南了解更多详情。</p></p>
                                   
                                                <p style="font-size: 20px;">关于objective-c - 获取例程中的死锁,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/9889475/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/9889475/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: objective-c - 获取例程中的死锁