4

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

我有第二种方法(我们称之为 method2),它获取与给定 CommunicationLink ID 关联的“主题”对象列表。就像method1method2检查服务器上是否已经存在 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

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

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

编辑

如果我正在处理推送通知的静态库的一部分,则此代码。我也在开发一个使用该库的测试应用程序。在我的根视图中method1调用- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken;并调用method2viewDidLoad

方法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;

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

谢谢

4

3 回答 3

2

这里的重点是您的处理方式:

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

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

如果您使用 NSURLResponse/Connection 或其他网络框架(AFNetworking 等),您将可以使用此类回调机制(这将采用某种委托方法的形式,或者您传递给网络请求的某些完成块) . 请提供更多详细信息以获取更多信息。

另一种方法是让您在单独的线程上管理工作流方法 1/方法 2,因此您可以等待而不阻塞 UI,但这会复杂得多。

编辑:

您可以使用您的

(^)(NSNumber *))successHandler

方法 1 的参数以链接方法 2 的执行。

或者,您可以执行以下操作:

  1. 运行时method1,设置一个标志,表示您的应用正在等待响应;

  2. 当收到响应时(即,在successHandler或中errorHandler),重置标志;

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

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

希望能帮助到你。

编辑2:

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

  1. 排除网络请求及其进一步处理(因此您可以从其内部和外部调用它们viewDidLoad);method2viewDidLoad

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

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

  4. 当您method1从您的应用程序代表处致电时,请在successHandler帖子中发出通知,以便任何相关方都知道已建立第一个连接;

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

这将需要对您的应用进行一些更改;即,您的视图控制器将需要支持“离线”模式,在这种模式下,它无法执行method2并向用户显示一些信息,具体取决于整体状态:无网络、等待响应、无响应等。

于 2013-02-27T15:13:28.453 回答
1

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

于 2013-02-27T14:57:51.657 回答
0

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

您可以使用pthread 互斥锁@synchronized指令(查看苹果的线程编程指南)。

于 2013-02-27T14:54:26.870 回答