首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSOperationQueue和ASIHTTPRequest

NSOperationQueue和ASIHTTPRequest
EN

Stack Overflow用户
提问于 2010-07-24 21:56:44
回答 2查看 2.5K关注 0票数 2

我正在为围绕ASIHTTPRequest编写的包装类编写测试用例。由于无法确定的原因,我的测试用例在ASIHTTPRequest完成之前就完成了失败。

下面是程序流的工作原理。

  1. 从我的测试用例开始。
  2. 在我的http engine对象中,指示它创建一个新列表。
  3. 创建新的ASIHTTPRequest对象并设置它。
  4. 将请求添加到操作队列。
  5. 等到那个队列是空的
  6. 检查是否调用了我的委托方法,如果没有调用则失败测试。

现在,大多数情况下,一切正常,测试通过,但有些时候测试失败,因为在操作队列将控制权返回给我的等待方法后调用了我的委托方法。

测试用例

代码语言:javascript
复制
// Set my flags to 'NO'
- (void)setUp {
    requestDidFinish = NO;
    requestDidFail = NO;
}

- (void)testCreateList {
    NSString *testList = @"{\"title\": \"This is a list\"}";

    JKEngine *engine = [[JKEngine alloc] initWithDelegate:self];
    NSString *requestIdentifier = [engine createList:jsonString];

    [self waitUntilEngineDone:engine];
    NSString *responseString = responseString_;
    [engine release];

    GHAssertNotNil(requestIdentifier, nil);
    GHAssertTrue(requestDidFinish, nil);
    GHAssertTrue([responseString hasPrefix:@"{\"CreateOrEditListResult\""], nil);

}

// Puts the test into a holding pattern until the http request is done
- (void)waitUntilEngineDone:(JKEngine *)engine {
    [engine waitUntilFinishedRunning]; 
}

// The delegate method called on successful completion
- (void)requestFinished:(NSString *)requestIdentifier withResponse:(NSString *)response {
    NSLog(@"request did finish");
    requestDidFinish = YES;
    responseIdentifier_ = [requestIdentifier retain];
    responseString_ = [response retain];
}

发动机程序

代码语言:javascript
复制
- (NSString *)createList:(NSString *)list {
    ASIHTTPRequest *request = [[ASIHTTPRequest alloc] initWithURL:[NSURL URLWithString:url]];
    [request addRequestHeader:@"Content-Type" value:kContentType];
    [request setRequestMethod:kPOST];
    request.delegate = self;

    [request appendPostData:[list dataUsingEncoding:NSUTF8StringEncoding]];

    NSString *requestIdentifier = [NSString stringWithNewUUID];

    [operationQueue_ addOperation:request];
    [operationDictionary_ setObject:request forKey:requestIdentifier];

    return requestIdentifier;
}

// This is the ASIHTTPRequest delegate method that's called on success
//   but it sometimes isn't called until AFTER the operationQueue finishes running
- (void)requestFinished:(ASIHTTPRequest *)request {
    DLog([request responseString]);

    BOOL canNotifiyDelegate = [self.delegate respondsToSelector:@selector(requestFinished:withResponse:)];
    if (canNotifiyDelegate) {
        NSArray *keyArray = [operationDictionary_ allKeysForObject:request];
        NSString *requestIdentifier = [keyArray objectAtIndex:0];
        [operationDictionary_ removeObjectForKey:requestIdentifier];

        if ([keyArray count] != 1) {
            ALog(@"It looks like a request was added to the operation dictionary multiple times. There's a bug somewhere.", nil);
        }

        [self.delegate requestFinished:requestIdentifier withResponse:[request responseString]];
    }
}

- (void)waitUntilFinishedRunning {
    [operationQueue_ waitUntilAllOperationsAreFinished];
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-07-26 11:01:34

ASIHTTPRequest调用主线程上的委托方法,默认情况下,GH-Unit在后台线程上运行其测试。我仍然对到底是怎么回事有些模糊,但迫使我的网络测试在主线程上运行,解决了这个问题。

我在网络测试类中实现了以下方法。

代码语言:javascript
复制
- (BOOL)shouldRunOnMainThread { 
    return YES;
}
票数 0
EN

Stack Overflow用户

发布于 2010-07-25 09:35:41

这就是ASIHTTPRequest的工作方式。在主线程上调用委托方法,而对委托的调用不会阻塞请求线程,因此在队列结束后完全有可能调用您的委托。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3327079

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档