菜鸟教程小白 发表于 2022-12-13 04:50:37

ios - 异步加载和 UITableView 的 -reloadData


                                            <p><p>我目前试图找出以下代码片段产生错误的原因。我正在使用 Google Calendar API 加载日历。但是我假设它异步加载其数据,因此当我调用 -reloadData 我的应用程序崩溃时没有控制台错误。 </p>

<pre><code>[ fetchCalendarsWithCompletion:^(GDataFeedBase *feed) {


   //CRASH !!! Trying to execute code on main thread
   dispatch_async(dispatch_get_main_queue(), ^{

      for(GDataEntryCalendar *cal in feed.entries){

            if(]){
                NSLog(@&#34;adding %@&#34;, cal.title.stringValue);
                ;
            }

      }

      ;

    });

}];
</code></pre>

<p>回溯看起来像这样:</p>

<pre><code>* thread #1: tid = 0xeabe5, 0x39ed81fc libsystem_kernel.dylib`__pthread_kill + 8, queue = &#39;com.apple.main-thread, stop reason = signal SIGABRT
    frame #0: 0x39ed81fc libsystem_kernel.dylib`__pthread_kill + 8
    frame #1: 0x39f3fa52 libsystem_pthread.dylib`pthread_kill + 58
    frame #2: 0x39e8902c libsystem_c.dylib`abort + 76
    frame #3: 0x392d798e libc++abi.dylib`abort_message + 74
    frame #4: 0x392f06e6 libc++abi.dylib`default_terminate_handler() + 254
    frame #5: 0x39928938 libobjc.A.dylib`_objc_terminate() + 192
    frame #6: 0x392ee1b2 libc++abi.dylib`std::__terminate(void (*)()) + 78
    frame #7: 0x392edd16 libc++abi.dylib`__cxa_rethrow + 102
    frame #8: 0x3992880e libobjc.A.dylib`objc_exception_rethrow + 42
    frame #9: 0x2f5615b6 CoreFoundation`CFRunLoopRunSpecific + 642
    frame #10: 0x2f561322 CoreFoundation`CFRunLoopRunInMode + 106
    frame #11: 0x342982ea GraphicsServices`GSEventRunModal + 138
    frame #12: 0x31e181e4 UIKit`UIApplicationMain + 1136
    frame #13: 0x000b8e44 MyApp`main(argc=1, argv=0x27d54d0c) + 116 at main.m:16
    frame #14: 0x39e21ab6 libdyld.dylib`start + 2
</code></pre>

<p>这里是委托(delegate)方法:</p>

<pre><code>- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{

    return calendarArray.count;

}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{


    static NSString *cellId = @&#34;CellIdentifier&#34;;
    CustomListCell *cell = ;

    if(cell == nil){

      cell = [ initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];

    }

    cell.calendar = ;

    return cell;

}
</code></pre></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>这里有两个问题。</p>

<p>首先,当您调用 <code>dispatch_get_main_queue()</code> 时,您实际上会返回主线程,这对于后台处理来说并不理想。</p>

<p>所以你需要把它改成:</p>

<pre><code>dispatch_queue_t concurrentQueue = dispatch_queue_create(&#34;MyQueue&#34;, NULL);
dispatch_async(concurrentQueue, ^{
    ... process your data here ...
});
</code></pre>

<p>第二个问题是你不能从后台线程调用<code>UITableView#reloadData</code>。所以你实际上只需要在主线程上安排一个:</p>

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

<p><code>reloadData</code> 的上述代码将进入您处理数据的 block 中,因此 <code>fetchCalendarsWithCompletion</code> 的完成 block 将类似于:</p>

<pre><code>dispatch_queue_t concurrentQueue = dispatch_queue_create(&#34;MyQueue&#34;, NULL);
dispatch_async(concurrentQueue, ^{
    ... process your data here ...
    dispatch_async(dispatch_get_main_queue(), ^{
      ;
    });
});
</code></pre></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 异步加载和 UITableView 的 -reloadData,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/19477447/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/19477447/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 异步加载和 UITableView 的 -reloadData