关于主线程崩溃的 NSNotification 帖子

Posted

技术标签:

【中文标题】关于主线程崩溃的 NSNotification 帖子【英文标题】:NSNotification post on main thread crashes 【发布时间】:2013-08-29 10:16:18 【问题描述】:

我有一个通知管理器类,它应该在主线程上发布所有通知。但我有一些崩溃报告。应用程序在此行崩溃:

dispatch_sync(dispatch_get_main_queue(), ^
                [[NSNotificationCenter defaultCenter] postNotificationName:aName object:anObject];

我想咨询一下如何解决这个问题。提前谢谢

#import "NotificationManager.h"

@interface NotificationManager ()

    NSNotificationCenter *center;

@end

@implementation NotificationManager

+ (NotificationManager *) sharedInstance

    static NotificationManager *instance;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^
        instance = [[NotificationManager alloc] init];
    );
    return instance;


- (void) postNotificationName:(NSString *)aName object:(id)anObject

    if (dispatch_get_current_queue() != dispatch_get_main_queue())
    
        dispatch_sync(dispatch_get_main_queue(), ^
            [[NSNotificationCenter defaultCenter] postNotificationName:aName object:anObject];
        );
    
    else
    
        [[NSNotificationCenter defaultCenter] postNotificationName:aName object:anObject];
    

@end

崩溃报告:

7   PLR 0x000e5d40  __51-[NotificationManager postNotificationName:object:]_block_invoke in NotificationManager.m on Line 27
8   libdispatch.dylib   0x39a14a88  _dispatch_barrier_sync_f_slow_invoke
9   libdispatch.dylib   0x39a105da  _dispatch_client_callout
10  libdispatch.dylib   0x39a13e44  _dispatch_main_queue_callback_4CF
11  CoreFoundation  0x318cf1b0  __CFRunLoopRun
12  CoreFoundation  0x3184223c  CFRunLoopRunSpecific
13  CoreFoundation  0x318420c8  CFRunLoopRunInMode
14  GraphicsServices    0x3542133a  GSEventRunModal
15  UIKit   0x3375e2b8  UIApplicationMain
16  PLR 0x000c5b4a  main in main.m on Line 9

【问题讨论】:

我已将崩溃报告信息添加到我的问题中 顺便说一句,dispatch_get_current_queue 在 ios 6 中已弃用。您应该始终删除条件并调度到主队列。 通过[NSThread isMainThread]可以知道是不是主线程。 但是,我认为您的if 不需要。只有 `dispatch_sync(dispatch_get_main_queue(), ^ [[NSNotificationCenter defaultCenter] postNotificationName:aName object:anObject]; );` 是有效的。 【参考方案1】:

我不能说这是否会解决您的问题,但您的 -postNotificationName:object: 方法可能最好这样写:

- (void) postNotificationName:(NSString *)aName object:(id)anObject

    if (![NSThread isMainThread])
    
        dispatch_sync(dispatch_get_main_queue(), ^ [self postNotificationName: aName object: anObject]; );
        return;
    

    [[NSNotificationCenter defaultCenter] postNotificationName:aName object:anObject];

【讨论】:

工作正常。我将在应用程序的下一次更新中实施此更改

以上是关于关于主线程崩溃的 NSNotification 帖子的主要内容,如果未能解决你的问题,请参考以下文章

NSNotification 检测其他程序的崩溃

关于MySQL线程池,这也许是目前最全面的实用帖!

Android 捕获主线程异常崩溃

与主线程相比,在辅助线程上崩溃是不是有优势?

如何在 Swift 中使用 NSNotification -> userInfo 发送对象数组

Android 捕获主线程异常崩溃