V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
tanorigin
V2EX  ›  iOS

[咨询] iOS 中线程加锁问题

  •  
  •   tanorigin · 2016-02-16 11:35:59 +08:00 · 2294 次点击
    这是一个创建于 3009 天前的主题,其中的信息可能已经有所发展或是发生改变。

    简介:这个函数的作用在于将用户注册到服务端。 app 内部会有多个 UI 事件可能会触发这个 function 。 function 内部主要是俩个方法各自开了若干的异步线程申请资源。

    需求:当有一处地方正在调用该 function 函数的时候 [结束标志为[someCaller doSth1] 或者 [someCaller doSth2];] ,另外一个地方触发调用这个函数的事件不允许进入此处调用 function 。

    尝试: 1.NSLock 加锁 不能在不同线程间加锁。 2.在 doSth1 和 doSth2 的位置放上一个属性,该属性在设置的时候加锁 — 未解决
    。。不知道 api 里边还有没有其他锁有此功能,或者用其他的方法来实现。谢谢~

    -(void) function{
    
        //func1WithCallback 内部开若干异步线程
        [caller1  func1WithCallback:^(id someData){
    
              //func2WithCallback 内部开若干异步线程
          [caller2  func2WithSuccessCallback:^(id someData2){
    
                   [someCaller1  doSth1];
    
                }errorCallback:^(id someErrorStatusData3){
    
                [someCaller2  doSth2];
              }];
        }];
    }
    

    谢谢您的解答。 祝新年快乐!

    9 条回复    2016-02-17 09:15:55 +08:00
    Elethom
        1
    Elethom  
       2016-02-16 11:53:23 +08:00 via iPhone
    類似 dispatch semaphore ?
    lecher
        2
    lecher  
       2016-02-16 12:11:07 +08:00 via Android
    抽象出来,做 Singleton 模式,这样实例化的时候都是同一个实例,加锁就等于全局锁。
    抽象出来,还是 Singleton 模式,不锁,但是用队列,请求处理封装成 block ,入队列,按开一个单独的线程处理队列的数据,保证一次只处理一个 HTTP 请求。
    tanorigin
        3
    tanorigin  
    OP
       2016-02-16 13:14:35 +08:00
    @lecher 恩 已经算是全局锁了。是个单例。 想着搞个队列,把触发的时间按顺序加入到队列中执行。 小白一枚,不知道怎么搞。
    expkzb
        4
    expkzb  
       2016-02-16 13:46:36 +08:00
    累不累,加个菊花转转不就好了,阻挡一下事件
    tanorigin
        5
    tanorigin  
    OP
       2016-02-16 14:09:58 +08:00
    @expkzb 这个方法在多个地方可能被调用。可能是某个通知触发,也可能是 UI 控件点击时间。所以有可能是后台进行。 用菊花加盖可能不妥。
    vincentxue
        6
    vincentxue  
       2016-02-16 16:48:27 +08:00
    以我的理解,弄个 BOOL 变量在开始结束判断一下不就行了吗,为什么要用锁?
    lecher
        7
    lecher  
       2016-02-16 20:01:34 +08:00 via Android   ❤️ 1
    把你的处理方法封装成单例模式,开放的接口不要直接执行处理,开放入队列的接口,处理方法封装一个 queue ,任务都扔里面去跑,新手的话有一个小坑, queue 跑完任务会自动释放,这时候有新任务进来需要重新实例化一个 queue 进行请求处理。
    gcd 的接口有相关的处理。封装一下就可以。


    我做过的的是利用 ASIqueue 的封装的单例,把数据处理从 view controller 剥离出来,写成 model ,开放入队接口,外部调用的时候,将需要数据和处理数据的函数通过 block 封装传给接口,接口拿到就把参数入队,执行完 HTTP 请求拿到数据,再回调 block 传进来的数据处理。

    其实原生的 queue 库也可以做到这些,自己封装一下试试看?
    jesse_luo
        8
    jesse_luo  
       2016-02-16 21:14:24 +08:00
    @vincentxue +1
    不过操作 bool 时要加锁
    dcty
        9
    dcty  
       2016-02-17 09:15:55 +08:00
    RAC

    - (void)test{
    [[self.signal1 then:^RACSignal *{
    return self.signal2;
    }] subscribeNext:^(id x) {

    } error:^(NSError *error) {

    }];
    }

    - (RACSignal *)signal1{
    return [RACSignal combineLatest:signals];
    }

    - (RACSignal *)signal2{
    return [RACSignal combineLatest:signals];
    }
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3192 人在线   最高记录 6547   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 14:06 · PVG 22:06 · LAX 07:06 · JFK 10:06
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.