我的應用程序以這種方式工作: - 創建相冊和拍照 - 送他們我的服務器上 - 讓圖片分析後的答案/補充信息。AFNetworking同步操作在NSOperationQueue iPhone上
我有一些問題與發送部分。下面是代碼
@interface SyncAgent : NSObject <SyncTaskDelegate>
@property NSOperationQueue* _queue;
-(void)launchTasks;
@end
@implementation SyncAgent
@synthesize _queue;
- (id)init
{
self = [super init];
if (self) {
self._queue = [[NSOperationQueue alloc] init];
[self._queue setMaxConcurrentOperationCount:1];
}
return self;
}
-(void) launchTasks {
NSMutableArray *tasks = [DataBase getPendingTasks];
for(Task *t in tasks) {
[self._queue addOperation:[[SyncTask alloc] initWithTask:t]];
}
}
@end
和SyncTask:
@interface SyncTask : NSOperation
@property (strong, atomic) Task *_task;
-(id)initWithTask:(Task *)task;
-(void)mainNewID;
-(void)mainUploadNextPhoto:(NSNumber*)photoSetID;
@end
@implementation SyncTask
@synthesize _task;
-(id)initWithTask:(Task *)task {
if(self = [super init]) {
self._task = task;
}
return self;
}
-(void)main {
NSLog(@"Starting task : %@", [self._task description]);
// checking if everything is ready, sending delegates a message etc
[self mainNewID];
}
-(void)mainNewID {
__block SyncTask *safeSelf = self;
[[WebAPI sharedClient] createNewPhotoSet withErrorBlock:^{
NSLog(@"PhotoSet creation : error")
} andSuccessBlock:^(NSNumber *photoSetID) {
NSLog(@"Photoset creation : id is %d", [photoSetID intValue]);
[safeSelf mainUploadNextPhoto:photoSetID];
}];
}
-(void)mainUploadNextPhoto:(NSNumber*) photoSetID {
//just admit we have it. won't explain here how it's done
NSString *photoPath;
__block SyncTask *safeSelf = self;
[[WebAPI sharedClient] uploadToPhotosetID:photoSetID withPhotoPath:photoPath andErrorBlock:^(NSString *photoPath) {
NSLog(@"Photo upload error : %@", photoPath);
} andSuccessBlock:^(NSString *photoPath) {
NSLog(@"Photo upload ok : %@", photoPath);
//then we delete the file
[safeSelf mainUploadNextPhoto:photoSetID];
}];
}
@end
每個網絡操作使用AFNetworking這樣做的話:
-(void)myDummyDownload:(void (^)(NSData * data))successBlock
{
AFHTTPClient* _httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:@"http://www.google.com/"]];
[_httpClient registerHTTPOperationClass:[AFHTTPRequestOperation class]];
NSMutableURLRequest *request = [_httpClient requestWithMethod:@"GET" path:@"/" nil];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
AFHTTPRequestOperation *operation = [_httpClient HTTPRequestOperationWithRequest:(NSURLRequest *)request
success:^(AFHTTPRequestOperation *operation, id data) {
if(dataBlock)
dataBlock(data);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Cannot download : %@", error);
}];
[operation setShouldExecuteAsBackgroundTaskWithExpirationHandler:^{
NSLog(@"Request time out");
}];
[_httpClient enqueueHTTPRequestOperation:operation];
}
我的問題是:我的連接是異步的,所以每個任務都會一起啓動,無需等到[self._queue setMaxConcurrentOperationCount:1]
在SyncAgent
即可完成。
我是否需要同步執行每個連接?我不認爲這是一個好主意,因爲連接永遠不應該這樣做,也因爲我可能會在別處使用這些方法,並且需要它們在後臺執行,但是我找不到更好的方法。任何想法 ?
哦,如果在我的代碼中有任何錯誤/拼寫錯誤,我可以向你保證,當我在粘貼它之前總結它時,它現在沒有任何問題。
謝謝!
PS:很抱歉,我找不到更好的解決問題的方法。
編輯:我發現,使用信號量更容易建立和理解:How do I wait for an asynchronously dispatched block to finish?
我必須承認我想到了。這接近了一些不好意思,但我想我會做到這一點。我正在考慮使用'dispatch_sync'正確執行,爲我所有的上傳文件設置一個隊列,但這個解決方案更容易。 – dvkch
您應該用GCD dispatch_groups替換NSCondition。主要看'dispatch_group_enter','dispatch_group_wait'和'dispatch_group_leave'。邁克阿什有[一個很好的教程](http://www.mikeash.com/pyblog/friday-qa-2009-09-04-intro-to-grand-central-dispatch-part-ii-multi-core-performance的.html)。 –