【问题标题】:Are UIKit target-actioin selectors always invoked on the main thread?UIKit 目标动作选择器是否总是在主线程上调用?
【发布时间】:2020-05-19 10:11:46
【问题描述】:

我在 CoreData fetchRequest 中有一个奇怪的崩溃,只能通过它在主线程之外执行来解释。

我在UITextEdit 上执行addTarget,当调用选择器方法时,进行一些数据检索。 我假设这将始终发生在主 UI 线程中。应该是这样吗?在我收到的崩溃报告中,我可以看到这个

Thread 1 name:
Thread 1:
0   libsystem_kernel.dylib          0x00000001abe4d198 mach_msg_trap + 8
1   libsystem_kernel.dylib          0x00000001abe4c60c mach_msg + 72 (mach_msg.c:103)
2   CoreFoundation                  0x00000001abff73b4 __CFRunLoopServiceMachPort + 148 (CFRunLoop.c:2575)
3   CoreFoundation                  0x00000001abff23e8 __CFRunLoopRun + 1160 (CFRunLoop.c:2931)
4   CoreFoundation                  0x00000001abff1c34 CFRunLoopRunSpecific + 424 (CFRunLoop.c:3192)
5   Foundation                      0x00000001ac334bcc -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 228 (NSRunLoop.m:374)
6   Foundation                      0x00000001ac334aac -[NSRunLoop(NSRunLoop) runUntilDate:] + 88 (NSRunLoop.m:421)
7   UIKitCore                       0x00000001b01c6160 -[UIEventFetcher threadMain] + 152 (UIEventFetcher.m:736)
8   Foundation                      0x00000001ac4639d0 __NSThread__start__ + 848 (NSThread.m:724)
9   libsystem_pthread.dylib         0x00000001abd8fd98 _pthread_start + 156 (pthread.c:896)
10  libsystem_pthread.dylib         0x00000001abd9374c thread_start + 8

这看起来像主线程。但是崩溃的调用栈在不同的地方

Thread 0 name:
Thread 0 Crashed:
0   CoreFoundation                  0x00000001ac02ebbc __CFStringChangeSizeMultiple + 300 (CFString.c:1063)
1   CoreFoundation                  0x00000001ac0298f0 __CFStringAppendBytes + 616 (CFString.c:1129)
2   CoreFoundation                  0x00000001ac0298f0 __CFStringAppendBytes + 616 (CFString.c:1129)
3   CoreFoundation                  0x00000001ac01b570 __CFStringAppendFormatCore + 12116 (CFString.c:0)
4   CoreFoundation                  0x00000001ac01bb10 _CFStringCreateWithFormatAndArgumentsAux2 + 152 (CFString.c:1919)
5   Foundation                      0x00000001ac33ca38 -[NSString initWithFormat:] + 56 (NSString.m:1891)
6   CoreData                        0x00000001b0a7d5b0 +[_PFRoutines valueForProcessArgument:] + 128 (_PFRoutines.m:1481)
7   CoreData                        0x00000001b0c0a8a8 _newFetchedRowsForFetchPlan_ST + 448 (NSSQLCore_Functions.m:4539)
8   CoreData                        0x00000001b0bfd0d4 _executeFetchRequest + 68 (NSSQLCore_Functions.m:4952)
9   CoreData                        0x00000001b098ebb8 -[NSSQLFetchRequestContext executeRequestCore:] + 40 (NSSQLFetchRequestContext.m:494)

【问题讨论】:

    标签: ios objective-c swift core-data uikit


    【解决方案1】:

    UIKit 有自己的内部事件获取线程(通常是“线程 1” - 你看到崩溃的那个)。使用 CoreData,最好在主线程上下文中使用 NSManagedObjectContext.perform(_:)。这将保证在块内执行的任何获取请求都发生在上下文的线程上。

    【讨论】:

      【解决方案2】:

      线程 0(你的第二个 sn-p)实际上是主线程。我可以判断,因为不是主线程的线程以调用 thread_start 或类似的方式开始。

      所以你正在获取并在主线程上崩溃。仅根据您的日志,我猜想崩溃是由于您在获取位置附近创建的格式化字符串而发生的。一个可能的罪魁祸首是创建NSPredicate 所需的格式化字符串。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-03-23
        • 1970-01-01
        • 1970-01-01
        • 2010-10-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多