在继续之前等待布尔值更改

时间:2013-02-27 14:50:51

标签: objective-c asynchronous

我有一个方法(让我们称之为method1),它向服务器(POST)发出异步请求,以创建具有给定ID的CommunicationLink对象。在发送请求之前,该方法检查服务器上是否已存在CommunicationLink。

我有第二个方法(让我们称之为method2),它获取与给定CommunicationLink ID关联的“主题”对象列表。就像method1一样,method2检查服务器上是否已存在CommunicationLink,如果没有,则会创建它(再次,通过向服务器发送异步请求)。

我遇到的问题是,当我启动应用程序时,method1method2会一个接一个地调用,所以我最终会得到这样的结果:

method1 checks if CommunicationLink exists ---> NO
  method1 sends a request to create CommunicationLink (async call)

method2 checks if CommunicationLink exist ---> NO because the previous call is not done yet
  method2 sends a request to create CommunicationLink

  method1 done
  method2 done

所以在服务器上,我最终得到2个相同ID的CommunicationLinks(我无法控制服务器端发生的事情)

如果method2已经向服务器发送了请求,那么“暂停”method1的最佳方法是什么?我可以在true中的通话之前将布尔设置为method1,并在请求完成后将其设置回false并在while (!myValue);中设置method2,但我觉得有一种更好的方法可以做到这一点。

修改

此代码是否是我正在处理推送通知的静态库的一部分。我还在处理使用该库的测试应用。在method1中调用- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken;,在我的根视图中调用method2 viewDidLoad

方法1

- (void)sendProviderDeviceToken:(NSData *)deviceToken contextUUID:(NSString *)contextUUID sourceUUID:(NSString *)sourceUUID topicUUID:(NSString *)topicUUID language:(NSString *)language;

创建CommLink的方法

- (void)createCommunicationLinkWithSuccessHandler:(void (^)(NSNumber *))successHandler errorHandler:(void (^)(NSError *))errorHandler;

方法2

- (void)retrieveSubscriptionForContext:(NSString *)contextUUID notificationTopic:(NSString *)notificationTopic completion:(void (^)(NSDictionary *))completion;

我希望能够直接在我的库中处理这种情况,而不必修改我的测试应用程序。 <{1}}和method1在同一个线程上被调用。

由于

3 个答案:

答案 0 :(得分:2)

这里的要点是你的处理方式:

“method1发送创建CommunicationLink(异步调用)的请求”

你应该提供某种回调。然后回调将执行/触发第二步。

如果您正在使用NSURLResponse / Connection或其他网络框架(AFNetworking等),您将拥有这种回调机制(这将采用某种委托方法的形式,或者您传入的一些完成块)网络请求)。请提供更多详细信息。

另一种方法是让你在一个单独的线程上管理工作流方法1 / method2,这样你就可以在不阻塞UI的情况下等待,但这会复杂得多。

编辑:

您可以使用

(^)(NSNumber *))successHandler

method1的参数,用于链接method2的执行。

或者,您可以做的是:

  1. 运行method1时,设置一个标记,说明您的应用正在等待回复;

  2. 收到回复后(即successHandlererrorHandler),重置旗帜;

  3. viewDidLoad中的
  4. ,在运行method2之前,检查标志的状态并仅在您不等待响应时执行method2

    < / LI>

    您需要创建从委托和视图控制器访问的某种状态信息。

    希望它有所帮助。

    编辑2:

    为了考虑到您可以在第一个网络请求完成之前加载视图控制器这一事实,我建议:

    1. 考虑viewDidLoad method2网络请求及其进一步处理(因此您可以在viewDidLoad内及其外部调用它们);

      < / LI>
    2. 将上面定义的方法注册为NSNotificationCenter通知的观察者;

    3. viewDidLoad中的
    4. ,如果方法1网络请求仍在进行,请不要调用步骤1中定义的方法;

    5. 当您从app appate调用method1时,请在successHandler发布通知,以便任何感兴趣的人知道第一个连接已建立;

      4b中。感谢在步骤2中注册的通知观察者,您查看控制器将能够更新其状态(并最终调用method2)。

    6. 这需要对您的应用进行一些更改;即,您的视图控制器将需要支持“离线”模式,在该模式下,它无法执行method2并根据整体状态向用户显示一些信息:无网络,等待响应,无响应等。< / p>

答案 1 :(得分:1)

如果你真的不需要等待第二种方法,那么KVO就是一种方便的方法。让您的对象等待其上的属性或其他对象更改为observeValueForKeyPath:ofObject:change:context:

答案 2 :(得分:0)

当然最好的方法是使用互斥锁:这是解决此类问题的标准方法。

您可以使用pthread mutexes@synchronized指令(请查看苹果的Threading Programming Guide)。