多线程调用引起的问题

作者: _Thinking_ | 来源:发表于2016-08-13 17:24 被阅读96次

今天发现一个老问题引起的崩溃,记录一下。

先有问题的代码:


@implementation LogicHandle

- (instancetype)init
{
    if (self = [super init]) {
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(onNotification)
                                                     name:@"kLogicNotification" object:nil];
    }
    
    return self;
}

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (void)onNotification
{
    [self showLog];
    [self showLog];
    [self showLog];
    [self showLog];
}

- (void)showLog
{
    NSLog(@"%@", self);
}

@end
//Post通知代码
- (void)postNotificationInBackground
{
    dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [[NSNotificationCenter defaultCenter] postNotificationName:kLogicNotification object:nil];
    });
}


常规的通知接收模型大致都是这样格式,但是这种方式在处理多线程的调用时会有问题。

由于PostNotification是在另一个线程的,所以 onNotification 也会在另一个线程执行。 这个时候很多人会认为是不是多线程访问对象引起的崩溃?那加个锁可以解决问题吗?

- (void)onNotification
{
    @synchronized (self) {
        xxx;
        xxx;
    }
}

没错, 多线程访问数据时会有问题,但很明显这里只是输出一下 self, 并没有涉及到数据的修改,所以这种方式的加锁是不能解决问题的。

原因:

当后台线程在执行 onNotification 方法的时候,执行到一半,其他线程把对象释放了。

解决方法:

  • 保证在同一线程发通知
  • 如果要支持多线程调用,可以用 "强引用" 确保对象不被释放。
- (void)mutithread_message
{
    __strong __typeof(self) strongSelf = self;
    [strongSelf op];
}

这种其实就是 block 里面常规的 weak-strong 的写法,只是很少会直接写到函数里面。

相关文章

  • 多线程调用引起的问题

    今天发现一个老问题引起的崩溃,记录一下。 先有问题的代码: 常规的通知接收模型大致都是这样格式,但是这种方式在处理...

  • ArrayList多线程调用add()可能出现的问题

    ArrayList多线程调用add()可能出现的问题 一 ArrayList在多线程调用Add()添加元素时的下...

  • 多线程调用问题2

    前言 最近遇到一个崩溃,都是一些基础问题没注意引起的。查找问题的时候还是花了一些时间,感觉还是有必要记录一下。 崩...

  • Python基础学习9

    多线程编程知识点记录:1、单线程函数如何转换为多线程1)线程函数调用 2)线程类调用 问题解答1:老师,我想不明白...

  • Android:多线程总结

    多线程总结 问题一:多线程join如何实现? join用来等待一个线程完成。join方法会调用wait函数,这个w...

  • python的多线程类变量共享

    问题说明 在同一个类中启动多线程的方法,和多线程执行的方法如果都在同一个类中,启动多线程时 通过self调用方法名...

  • dubbo初了解 异步调用

    异步调用 基于 NIO 的非阻塞实现并行调用,客户端不需要启动多线程即可完成并行调用多个远程服务,相对多线程开销较...

  • 2019-02-02-vertx下的递归调用

    vertx 下 基于 future 写法的 递归 调用,将不会引起 传统的java递归调用的栈溢出问题。cpu占用...

  • 多线程-threading模块

    args参数是元组,该多线程调用的参数kwargs参数是字典,字典键值对是该多线程调用的参数形参-值

  • Java基础之ConcurrentHashMap

    HashMap存在的问题: HashMap线程不安全 因为多线程环境下,使用Hashmap进行put操作可能会引起...

网友评论

    本文标题:多线程调用引起的问题

    本文链接:https://www.haomeiwen.com/subject/erxysttx.html