具有异步操作的方法中的线程安全

时间:2014-12-21 05:32:45

标签: ios objective-c multithreading asynchronous

我有这个方法

- (void) checkIfShouldSendReadingsToServerAsync
    {
    // Check if I want to send the data
    // All other threads should wait hear until I signal them to continue
    if (!self.lastSendRequestToServerDateTime ||
        ([[NSDate date] timeIntervalSinceDate:self.lastSendRequestToServerDateTime]/60.0) > intervalBetweenRequestsToServerInMinutes.doubleValue)
        {
        // Read data from the SQLite database asynchronous and a completion block
        // This call uses a NSOperationQueue block
        [self.sqliteStore readingsToSendToServer:^(NSArray *readingsArray)
            {
            // Loaded the values, now check if I should send them
            if (readingsArray &&
                readingsArray.count > 0)
                {
                // Convert array of objects to JSON
                NSString* json = [self.sqliteStore readingsArrayToJSON:readingsArray];
                // Send the JSON to the server using NSURLSession
                [[WEEServiceRepository sharedInstance] sendJSONReadings:json withCompletionHandler:^(NSError *error, NSURLResponse *response)
                    {
                    // REST POST call ended, check the status code
                    NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
                    NSInteger statusCode = httpResponse.statusCode;
                    self.lastSendRequestToServerDateTime = [NSDate date];
                    switch (statusCode)
                        {
                        case 200:
                        case 201:
                        case 204:
                            {
                            // This call uses a NSOperationQueue block
                            [self.sqliteStore updateReadingsWithSentToServerYes:readingsArray andCompletionBlock:^(BOOL succeed)
                                {
                                // Here allow all other threads or the same thread to enter
                                }];
                                break;
                            }
                        default:
                            {
                            // Or here signal to continue
                            }
                        }
                    }];
                }
            }];
        }
    }

我希望整个方法都是线程安全的,直到服务调用返回并发出信号表明其他线程可以继续它,这应该让它们保持一致。

此代码将在应用程序位于前台但在后台运行时运行。 我试过信号量,但有一段时间后我发现它停在后台,可能会出现死锁?但它不应该!我真的不想使用@synchronized,或者我错了并继续尝试?也许只使用NSLock或NSRecursiveLock?

我尝试找到最合适的方法来锁定和解锁代码段,尤其是在使用异步方法时。

1 个答案:

答案 0 :(得分:0)

当你必须在this example的帮助下处理一系列依赖的异步操作时,我确保线程安全,从NSOperation重写并实现属性isExecuting,isFinished,start方法可以让你控制队列将释放操作并进入下一个操作,在我的情况下将NSOperationQueue.maxConcurrentOperationCount设置为1.