我有一个只有一个方法的类,它使用URLConnection将序列化的NSDictionary发送到某个URL上的脚本,然后调用完成块。以下是该方法的代码:
- (void)sendDictionary:(NSDictionary *)dictionary toScript:(NSString *)scriptName completion:(void (^) (id response))completionBlock
{
...Serialize data and add it to an NSURLRequest request...
H2URLConnection *connection = [[H2URLConnection alloc]initWithRequest:request];
//Define a semaphore to block execution of later statements until the signal is received.
dispatch_semaphore_t sem = dispatch_semaphore_create(0);
[connection setCompletionBlock:[^(id obj, NSError *err)
{
if (!err) {
//Catch the server response
NSString *receivedString = [[NSString alloc] initWithData:obj encoding:NSUTF8StringEncoding];
NSLog( @"ChecklistAppNetworkManager received string: %@", receivedString);
//Convert the JSON response into an NSDictionary
NSError *otherError;
id deserializedJSON = [NSJSONSerialization JSONObjectWithData:obj options:kNilOptions error:&otherError];
if (otherError) {
NSLog(@"ChecklistAppNetworkManager JSON Error: %@", otherError.description);
}
[completionBlock invoke];
NSLog(@"ChecklistAppNetworkManager JSON Response: %@", deserializedJSON);
//Dispatch the semaphore signal so that the main thread continues.
dispatch_semaphore_signal(sem);
} else {
NSLog(@"ChecklistAppNetworkManager encountered an error connecting to the server: %@", [err description]);
}
}copy]];
//Finalize and initate the connection.
[connection start];
//Since block is dispatched to main queue, stall with a loop until the semaphore signal arrives.
while (dispatch_semaphore_wait(sem, DISPATCH_TIME_NOW)) {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:10]];
}
}
我试图在另一个类中调用这个类实例的方法,其中完成块被定义。这是我遇到“EXC_BAD_ACCESS”错误的代码:
- (void)doSomeServerTask
{
H2ChecklistAppNetworkManager *currentNetworkManager = ((H2AppDelegate *)[[UIApplication sharedApplication]delegate]).networkManager; //Instantiate class where that method is defined
NSMutableDictionary *dictonary = [NSMutableDictionary dictionary];
...populate dictionary...
[currentNetworkManager sendDictionary:dictionary toScript:@"script.php" completion:[^(id response)
{ //THIS iS THE LINE WHERE THE BAD ACCESS OCCURS
NSLog(@"LoginViewController received response: %@", response);
} copy]];
}
任何帮助都将不胜感激!
H2URLConnection
是一个NSURLConnection
子类?标准的initWithRequest
实际上会启动连接,所以除非你已经覆盖它,使其调用带有startImmediately
为NO
的NSURLConnection
方法initWithRequest
,否则你会启动两次连接。确保使用startImmediately: NO
版本。我建议打印request
,以便我们可以确保URL不是nil
之类的东西。 - RobcompletionBlock
的方式不是[completionBlock invoke];
而是completionBlock(deserializedJSON)
。或者,除非你指定completionBlock
是nonnull
的,为谨慎起见,应该这样写if (completionBlock) { completionBlock(deserializedJSON) }
。 - Rob