我正在使用UNIRest library
而我正试图在ViewController
的响应中切换到另一个HTTP GET method
。
[[UNIRest get:^(UNISimpleRequest *request) {
[request setUrl:GEtFamilyMembers];
}] asJsonAsync:^(UNIHTTPJsonResponse* response, NSError *error) {
NSLog(@"res: %@", response.body);
if (response.code == 200) {
GCHFamilyMembersViewConroller* fmViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"gchFamilyMembers"];
self.navigationController.viewControllers = @[fmViewController];
[self.mm_drawerController setCenterViewController:self.navigationController withCloseAnimation:YES completion:nil];
} else {
[self showToast:@"Something went wrong, Please try again after some time."];
}
}];
即使在使用NSLog
打印回复后也是如此。大约30秒没有任何事情发生。然后突然app崩溃了。
我认为是因为Asynch调用阻止UI
所以我厌倦了这样的方法:
- (void) gotoSelectFamilyMembers {
dispatch_async(dispatch_get_main_queue(), ^{
GCHFamilyMembersViewConroller* fmViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"gchFamilyMembers"];
self.navigationController.viewControllers = @[fmViewController];
[self.mm_drawerController setCenterViewController:self.navigationController withCloseAnimation:YES completion:nil];
});
}
但应用程序仍然崩溃。
早些时候,当我使用Synchronous
电话时,它正在运行。但是不是现在。
请帮忙!
编辑:
2016-05-02 17:58:22.695 Checkme Mobile[6208:136321] *** Assertion failure in -[UIKeyboardTaskQueue waitUntilAllTasksAreFinished], /SourceCache/UIKit_Sim/UIKit-3347.44.2/Keyboard/UIKeyboardTaskQueue.m:374
2016-05-02 17:58:22.728 Checkme Mobile[6208:136224] NSScanner: nil string argument
2016-05-02 17:58:22.728 Checkme Mobile[6208:136224] NSScanner: nil string argument
2016-05-02 17:58:23.730 Checkme Mobile[6208:136224] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[UIKeyboardTaskQueue waitUntilAllTasksAreFinished] may only be called from the main thread.'
*** First throw call stack:
(
0 CoreFoundation 0x00000001094a6c65 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x0000000108da2bb7 objc_exception_throw + 45
2 CoreFoundation 0x00000001094a6aca +[NSException raise:format:arguments:] + 106
3 Foundation 0x00000001089b798f -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 195
4 UIKit 0x0000000107d887d6 -[UIKeyboardTaskQueue waitUntilAllTasksAreFinished] + 151
5 UIKit 0x0000000107829912 -[UIKeyboardImpl setDelegate:force:] + 473
6 UIKit 0x0000000107ad44ad -[UIPeripheralHost(UIKitInternal) _reloadInputViewsForResponder:] + 1002
7 UIKit 0x0000000107adc834 -[UIPeripheralHost(UIKitInternal) _preserveInputViewsWithId:animated:reset:] + 504
8 UIKit 0x000000010778e181 -[UINavigationController navigationTransitionView:didStartTransition:] + 578
9 UIKit 0x00000001079948bc -[UINavigationTransitionView transition:fromView:toView:] + 655
10 UIKit 0x0000000107792170 -[UINavigationController _startTransition:fromViewController:toViewController:] + 2984
11 UIKit 0x0000000107792408 -[UINavigationController _startDeferredTransitionIfNeeded:] + 523
12 UIKit 0x0000000107792ece -[UINavigationController __viewWillLayoutSubviews] + 43
13 UIKit 0x00000001078dd6d5 -[UILayoutContainerView layoutSubviews] + 202
14 UIKit 0x00000001076b09eb -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 536
15 QuartzCore 0x0000000109d83ed2 -[CALayer layoutSublayers] + 146
16 QuartzCore 0x0000000109d786e6 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 380
17 QuartzCore 0x0000000109d78556 _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 24
18 QuartzCore 0x0000000109ce486e _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 242
19 QuartzCore 0x0000000109ce5a22 _ZN2CA11Transaction6commitEv + 462
20 QuartzCore 0x0000000109ce5c99 _ZN2CA11Transaction14release_threadEPv + 199
21 libsystem_pthread.dylib 0x000000010a35172a _pthread_tsd_cleanup + 86
22 libsystem_pthread.dylib 0x000000010a351451 _pthread_exit + 117
23 libsystem_pthread.dylib 0x000000010a3506cd _pthread_wqthread + 879
24 libsystem_pthread.dylib 0x000000010a34e40d start_wqthread + 13
)
2016-05-02 17:58:23.730 Checkme Mobile[6208:136321] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[UIKeyboardTaskQueue waitUntilAllTasksAreFinished] may only be called from the main thread.'
*** First throw call stack:
(
0 CoreFoundation 0x00000001094a6c65 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x0000000108da2bb7 objc_exception_throw + 45
2 CoreFoundation 0x00000001094a6aca +[NSException raise:format:arguments:] + 106
3 Foundation 0x00000001089b798f -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 195
4 UIKit 0x0000000107d887d6 -[UIKeyboardTaskQueue waitUntilAllTasksAreFinished] + 151
5 UIKit 0x0000000107829912 -[UIKeyboardImpl setDelegate:force:] + 473
6 UIKit 0x0000000107ad44ad -[UIPeripheralHost(UIKitInternal) _reloadInputViewsForResponder:] + 1002
libc++abi.dylib: 7 UIKit 0x0000000107adc834 -[UIPeripheralHost(UIKitInternal) _preserveInputViewsWithId:animated:reset:] + 504
8 UIKit 0x000000010778e181 -[UINavigationController navigationTransitionView:didStartTransition:] + 578
9 UIKit 0x00000001079948bc -[UINavigationTransitionView transition:fromView:toView:] + 655
10 UIKit 0x0000000107792170 -[UINavigationController _startTransition:fromViewController:toViewController:] + 2984
11 UIKit 0x0000000107792408 -[UINavigationController _startDeferredTransitionIfNeeded:] + 523
12 UIKit 0x0000000107792ece -[UINavigationController __viewWillLayoutSubviews] + 43
13 UIKit 0x00000001078dd6d5 -[UILayoutContainerView layoutSubviews] + 202
14 UIKit 0x00000001076b09eb -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 536
15 QuartzCore 0x0000000109d83ed2 -[CALayer layoutSublayers] + 146
16 QuartzCore 0x0000000109d786e6 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 380
17 QuartzCore 0x0000000109d78556 _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 24
18 QuartzCore 0x0000000109ce486e _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 242
19 QuartzCore 0x0000000109ce5a22 _ZN2CA11Transaction6commitEv + 462
20 QuartzCore 0x0000000109ce5c99 _ZN2CA11Transaction14release_threadEPv + 199
21 libsystem_pthread.dylib 0x000000010a35172a _pthread_tsd_cleanup + 86
22 libsystem_pthread.dylib 0x000000010a351451 _pthread_exit + 117
23 libsystem_pthread.dylib 0x000000010a3506cd _pthread_wqthread + 879
24 libsystem_pthread.dylib 0x000000010a34e40d start_wqthread + 13
)
terminating with uncaught exception of type NSExceptionlibc++abi.dylib:
terminating with uncaught exception of type NSException
(lldb)
编辑:
- (IBAction)loginAction:(id)sender {
self.email = usernameTextField.text;
self.password = passwordTextField.text;
if(!([self.email isEqualToString:@""] && [self.password isEqualToString:@""])) {
[self performLogin];
} else{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"error" message:@"Enter both username and password." delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
[alert show];
}
}
- (void) performLogin {
NSDictionary* headers = @{@"Content-Type": @"application/x-www-form-urlencoded"};
NSDictionary* parameters = @{@"username": self.email, @"password": self.password};
[[NSThread currentThread] isMainThread] ? NSLog(@"1MAIN THREAD") : NSLog(@"1NOT MAIN THREAD");
self.loginConnection = [[UNIRest post:^(UNISimpleRequest *request) {
[request setUrl:LOgin];
[request setHeaders:headers];
[request setParameters:parameters];
}] asJsonAsync:^(UNIHTTPJsonResponse* response, NSError *error) {
// This is the asyncronous callback block
[[NSThread currentThread] isMainThread] ? NSLog(@"2MAIN THREAD") : NSLog(@"2NOT MAIN THREAD");
UNIJsonNode *body = response.body;
NSData *rawBody = response.rawBody;
NSString *string = [[NSString alloc] initWithData:rawBody encoding:NSUTF8StringEncoding];
NSLog(@"response signup: %@", string);
if (response.code == 200) {
[self processLoginResponse:body];
}
}];
}
- (void) processLoginResponse:(UNIJsonNode *) body {
if ([body.JSONObject[@"status"] boolValue] == YES) {
NSString *firstName = body.JSONObject[@"firstName"];
NSString *lastName = body.JSONObject[@"lastName"];
NSString *name = [firstName stringByAppendingString:lastName];
NSMutableDictionary *mDictionary = [[NSMutableDictionary alloc] init];
[mDictionary setObject:body.JSONObject[@"accountId"] forKey:@"accountId"];
[mDictionary setObject:name forKey:@"name"];
[mDictionary setObject:@"Custodian" forKey:@"relation"];
[self fetchFamilyMembers:mDictionary];
} else {
[self showAlert:body.JSONObject[@"message"]];
}
}
- (void) fetchFamilyMembers:(NSMutableDictionary *) mDictionary {
[[NSThread currentThread] isMainThread] ? NSLog(@"3MAIN THREAD") : NSLog(@"3NOT MAIN THREAD");
self.fmConnection = [[UNIRest get:^(UNISimpleRequest *request) {
[request setUrl:GEtFamilyMembers];
}] asJsonAsync:^(UNIHTTPJsonResponse* response, NSError *error) {
NSLog(@"res: %@", response.body);
if (response.code == 200) {
[[NSThread currentThread] isMainThread] ? NSLog(@"4MAIN THREAD") : NSLog(@"4NOT MAIN THREAD");
NSData *rawBody = response.rawBody;
NSString *string = [[NSString alloc] initWithData:rawBody encoding:NSUTF8StringEncoding];
NSLog(@"family signup: %@", string);
[[NSThread currentThread] isMainThread] ? NSLog(@"5MAIN THREAD") : NSLog(@"5NOT MAIN THREAD");
[self processFamilyMembersResponse:mDictionary :response.body];
} else {
[self showToast:@"Something went wrong, Please try again after some time."];
}
}];
}
- (void) processFamilyMembersResponse:(NSMutableDictionary *) mDictionary :(UNIJsonNode *) body {
NSArray *fmArray = body.JSONArray;
if (fmArray == nil || [fmArray count] == 0) {
NSNumber *accountId = (NSNumber *)[mDictionary objectForKey:@"accountId"];
} else {
NSMutableArray *mArray = [[NSMutableArray alloc] init];
[mArray addObject:mDictionary];
for (int i = 0; i < fmArray.count; i++) {
NSDictionary *fmDictionary = [fmArray objectAtIndex:i];
mDictionary = [[NSMutableDictionary alloc] init];
NSNumber *accountId = (NSNumber *)[fmDictionary objectForKey:@"id"];
[mDictionary setObject:accountId forKey:@"accountId"];
[mDictionary setObject:[fmDictionary objectForKey:@"name"] forKey:@"name"];
[mDictionary setObject:[fmDictionary objectForKey:@"relation"] forKey:@"relation"];
[mArray addObject:mDictionary];
}
[[NSThread currentThread] isMainThread] ? NSLog(@"6MAIN THREAD") : NSLog(@"6NOT MAIN THREAD");
[self gotoSelectFamilyMembers:mArray];
}
}
- (void) gotoSelectFamilyMembers:(NSMutableArray *) mArray {
dispatch_async(dispatch_get_main_queue(), ^{
GCHFamilyMembersViewConroller* fmViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"gchFamilyMembers"];
fmViewController._tblData = mArray;
self.navigationController.viewControllers = @[fmViewController];
[self.mm_drawerController setCenterViewController:self.navigationController withCloseAnimation:YES completion:nil];
});
}
答案 0 :(得分:1)
尝试以下代码:
dispatch_async(dispatch_get_main_queue(), ^{
GCHFamilyMembersViewConroller* fmViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"gchFamilyMembers"];
fmViewController._tblData = mArray;
((AppDelegate*)[[UIApplication sharedApplication]delegate]).navigationController.viewControllers = @[fmViewController];
[self.mm_drawerController setCenterViewController:((AppDelegate*)[[UIApplication sharedApplication]delegate]).navigationController withCloseAnimation:YES completion:nil];
});
答案 1 :(得分:0)
您正在使用Unirest
的异步调用,应在UI thread (Main thread)
上调用响应。通常类似于此的库在主线程上提供结果。因此,我认为您无需在dispatch_async
上专门致电main queue
。但是,您可以使用以下检查来查看是否在主线程上调用它。
[[NSThread currentThread] isMainThread] ? NSLog(@"MAIN THREAD") : NSLog(@"NOT MAIN THREAD");
这是我怀疑的
ViewController
创建方法存在一些错误并且正在消耗时间我建议您在没有任何Web服务调用的情况下调用以下内容来确认它们不会导致崩溃。
GCHFamilyMembersViewConroller* fmViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"gchFamilyMembers"];
self.navigationController.viewControllers = @[fmViewController];
[self.mm_drawerController setCenterViewController:self.navigationController withCloseAnimation:YES completion:nil];