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

2016-02-16 11:35:59 +08:00
 tanorigin

简介:这个函数的作用在于将用户注册到服务端。 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];
          }];
    }];
}

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

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


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

其实原生的 queue 库也可以做到这些,自己封装一下试试看?
jesse_luo
2016-02-16 21:14:24 +08:00
@vincentxue +1
不过操作 bool 时要加锁
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];
}

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/256785

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX