代码之家  ›  专栏  ›  技术社区  ›  kubi

nsOperationQueue和asihttpRequest

  •  2
  • kubi  · 技术社区  · 14 年前

    我正在为一个包装类编写测试用例 ASIHTTPRequest . 由于我不能确定的原因,我的测试用例失败了 之前 AsihttpRequest完成。

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

    1. 从我的测试用例开始。
    2. 初始化我的HTTP引擎对象,指示它创建新列表
    3. 创建新的asihttpRequest对象并设置它。
    4. 将请求添加到操作队列。
    5. 等待队列为空
    6. 检查是否调用了我的委托方法,如果没有,则测试失败。

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

    测试用例

    // 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];
    }
    

    发动机代码

    - (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];
    }
    
    2 回复  |  直到 13 年前
        1
  •  1
  •   pokeb    14 年前

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

        2
  •  0
  •   kubi    14 年前

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

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

    - (BOOL)shouldRunOnMainThread { 
        return YES;
    }
    
    推荐文章