简体   繁体   中英

cannot execute method insde dispatch_async()

I am facing something I cannot sort out. I am downloading json data and instantiating Core Data objects with the returned value (inside a dispatch_async(get_main_queue)). I try to present an other view (with tableView containing these objects) after everything is completed but my tableviewcontrollers are not called. However everything works fine if I present my viewController from a method outside this block (which is inside connectionDidFinishing NSURLConnection).

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {

id jsonObject = [NSJSONSerialization JSONObjectWithData:_downloadedData options:NSJSONReadingAllowFragments error:&error];


if ([jsonObject isKindOfClass:[NSArray class]]) {

    NSArray *deserializedArray = (NSArray *)jsonObject;

    if (deserializedArray.count > 0) {

        dispatch_async(dispatch_get_main_queue(), ^{
            for (NSDictionary *jsonElement in deserializedArray)
            {

                // Create a new location object and set its props to JsonElement properties
                Patient *syncPatient = [[PatientStore sharedStore] createPatient];


                syncPatient.firstName = jsonElement[@"firstname"];
                syncPatient.lastName = jsonElement[@"lastname"];      
            }

        });
        [self login]; // --> does not work.
    }

}
}

[self login] does not work. But it works if I call it from outside the didFinishLoading method.

It has to do I think with the dispatch_async() but I don't know how to call this method automatically from outside (for example with a "I have finish" notification).

Does anyone could help?

Thanks a lot!

UPDATE

It does not work either inside the block. It looks like [self login] happened before the for loop instructions.

if (deserializedArray.count > 0) {

    dispatch_async(dispatch_get_main_queue(), ^{
        for (NSDictionary *jsonElement in deserializedArray)
        {

            // Create a new location object and set its props to JsonElement properties
            Patient *syncPatient = [[PatientStore sharedStore] createPatient];


            syncPatient.firstName = jsonElement[@"firstname"];
            syncPatient.lastName = jsonElement[@"lastname"];      
        }
    [self login]; // --> does not work either here. As if it was executed before what is inside the for loop.
    });

}

} }

[self login] is executed immediately after the core data save starts because it is outside the block. If you put it inside, it will execute after the loop finishes.

You can test this with a simple command line project, which this content in main.swift:

import Foundation

dispatch_async(dispatch_get_main_queue()) {
    var j = 0
    for _ in 1...1000 { j++ }
    println("The value of j is \(j).")
}
dispatch_main()

Output: The value of j is 1000.

The println is clearly executed after the loop.

After creating your objects, do not forget to save:

[managedObjectContext save:nil];

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM