Reputation: 57
I have to search database using keyword typed from key board from iphone. When ever i search the key board halts. and if i run in the background then i find an empty array. I want both key board so that key board doesnot halts and wait until array is full with data.I am using objective-c.
dispatch_semaphore_t task = dispatch_semaphore_create(0);
manager.completionQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
NSURLSessionDataTask *dataTask = [manager dataTaskWithRequest:request completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
if (error) {
} else {
//int i=0;
//NSLog(@"%@",responseObject);
header=responseObject;
dispatch_semaphore_signal(task);
}
}];
[dataTask resume];
dispatch_semaphore_wait(task, DISPATCH_TIME_FOREVER);
return header;
Upvotes: 1
Views: 91
Reputation: 438162
You've taken an inherently asynchronous method, dataTaskWithRequest
, and have made it synchronous (i.e. it blocks the thread from which it was called). Get rid of all of that semaphore stuff. It's a really bad pattern, anyway.
I assume you did that because you wanted to return
data from a network call. You shouldn't do that. You should use a completion handler pattern, e.g.
For example, let's imagine your method currently looks like:
- (id)performRequest:(NSURLRequest *)request {
__block id header;
manager.completionQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
NSURLSessionDataTask *dataTask = [manager dataTaskWithRequest:request completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
if (error) {
} else {
header = responseObject;
}
dispatch_semaphore_signal(semaphore);
}];
[dataTask resume];
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
return header;
}
You should change it to a void
return type, and add a completionHandler
parameter:
- (void)performRequest:(NSURLRequest *)request completionHandler:(void (^)(id _Nullable responseObject, NSError * _Nullable error))completionHandler {
manager.completionQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
NSURLSessionDataTask *dataTask = [manager dataTaskWithRequest:request completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
if (error) {
completionHandler(nil, error);
} else {
completionHandler(responseObject, nil);
}
}];
[dataTask resume];
}
And you'd call it like so:
[self performRequest:request completionHandler:^(id responseObject, NSError *error) {
// use responseObject and error here
}];
// but not here
Upvotes: 1