objective C处理while循环中的其他事件

时间:2014-02-12 18:54:14

标签: objective-c json multithreading events

有没有办法强制您的应用程序处理其他事件?我有一个循环,应该等待10秒钟的json响应。问题似乎是didReceiveData事件之前的循环进程可以运行。

JsonArray是一个NSArray属性。

这是我在Session.m中的代码:

-(BOOL)logIn
{
    JsonArray = nil;
    if (([Password class] == [NSNull class]) || ([Password length] == 0))
        return NO;

    if (([Username class] == [NSNull class]) || ([Username length] == 0))
        return NO;

    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:URL_ALL_PROPERTIES]
                                             cachePolicy:NSURLRequestUseProtocolCachePolicy
                                         timeoutInterval:10.0];

    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    [connection start];

    if (!connection)
    {
        return NO;
    }

    int time = CFAbsoluteTimeGetCurrent();

    while (!JsonArray)
    {
        if (CFAbsoluteTimeGetCurrent() - time == 10)
        {
            NSLog(@"breaking loop");
            break;
        }
        // process events here
    }

    if (!JsonArray) return NO;

    NSLog(@"JsonArray not nil");
    return YES;
}

didReceiveData处理程序:

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    NSLog(@"Data received");
    NSError *e = nil;
    JsonArray = nil;

    JsonArray = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&e];
    if (!JsonArray)
    {
        JsonArray = nil;
        Connected = NO;
        return;
    }
    Connected = YES;
}

2 个答案:

答案 0 :(得分:2)

拥抱你想要做的事情的异步性质。从login方法中删除返回并添加完成块。将完成块存储在属性(副本)中,并从connectionDidFinishLoading:调用它。

typedef void (^MYCompletionHandler)(BOOL success);

@property (nonatomic, copy) void (^MYCompletionHandler)(bool *) completion;

- (void)loginUserWithCompletion:(MYCompletionHandler)completion {

    self.completion = completion;

    // start your login processing here
}

// when the login response is received
self. completion(##DID_IT_WORK##);

您当前的代码不起作用,因为在您的硬循环运行时主runloop没有运行,因此委托方法排队等待处理。不要尝试使用run循环来解决它,正确处理异步性质。

答案 1 :(得分:1)

收到数据后,将调用didReceiveData方法。如果需要处理返回的数据,请在委托方法中执行。

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    // process your data in here     
}

logIn函数必须在调用didReceiveData之前完成。你不能阻止回应。这就是NSURLConnection的本质。