2011-08-16 25 views
35

Tôi đang sử dụng đoạn mã sau để lấy một số thông điệp và đưa chúng vào hộp thư của tôi."Pushing cùng dụ xem điều khiển nhiều hơn một lần không được hỗ trợ" ngoại lệ

MyInboxVC *inboxVC=[MyInboxVC get ]; 
//upload all the pending messages 
UINavigationController *devNavController=[[MyappMgr get]getDeveloperNavigationController ]; 

[devNavController pushViewController:inboxVC animated:YES]; 
[devNavController setNavigationBarHidden:NO]; 

tôi nhận được ngoại lệ

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Pushing the same view controller instance more than once is not supported (<MyInboxVC: 0x1452a0>)' 

có nghĩa là gì? Tôi đang làm gì sai?

Trả lời

62

Tôi tin rằng khi bạn làm một số hành động thật nhanh lon điều này xảy ra quá. Tôi xây dựng một cái gì đó trong như thế này:

if(![self.navigationController.topViewController isKindOfClass:[YOURCLASS class]]) { 

chỉnh sửa //

điều này xảy ra thường xuyên hơn trên các thiết bị cũ với hình ảnh động chậm, giống như iphone 3 hoặc 3gs

+0

tôi đã trải qua cùng một vấn đề trong một ứng dụng rất đơn giản. Điều này giải quyết nó cho tôi. – neoneye

+4

Tôi có séc này nhưng ngoại lệ vẫn tồn tại. Khi lần đẩy thứ hai xảy ra, topViewController vẫn chưa thay đổi. Nếu tôi đẩy mà không có hoạt hình, nó hoạt động. bất cứ ai có thể giúp đỡ về điều này? – edwardtoday

5

Điều đó có nghĩa là ViewController được trả lại từ [MyInboxVC get] đã có trong ngăn điều hướng devNavController. Bạn không thể thêm cùng một đối tượng vào ngăn xếp nhiều lần.

Rõ ràng, bạn đã có một MyInboxVC đẩy sớm hơn. Đảm bảo rằng bạn đã bật nó khi nó không còn cần thiết nữa.

Đó là "những gì nó có nghĩa là" câu trả lời, nhưng không có đủ thông tin để biết những gì bạn cần phải làm gì để sửa chữa nó.

tôi đoán là Navigation Ngăn xếp của bạn đang phát triển lớn hơn bạn đang mong đợi, có nghĩa là bạn đang không popping thường xuyên như bạn cần.

1

Đây là một hành vi mong đợi của UINavigationController nơi một ngoại lệ được ném khi cố gắng chuyển một bộ điều khiển xem mà đã có mặt trong ngăn xếp (nó có từ iOS 2.2).

17

Thứ nhất xử lý các vụ tai nạn nên nó không giết ứng dụng của bạn:

@try { 
    [self.navController pushViewController:viewController animated:NO]; 
} @catch (NSException * e) { 
    NSLog(@"Exception: %@", e); 
} @finally { 
    //NSLog(@"finally"); 
} 

Sau đó, nếu bạn nhận được lỗi sử dụng popTo

- (void)pushViewController:(UIViewController *)viewController { 
    if (viewController) { 
    @try { 
     [self.navController pushViewController:viewController animated:NO]; 
    } @catch (NSException * ex) { 
     //“Pushing the same view controller instance more than once is not supported” 
     //NSInvalidArgumentException 
     NSLog(@"Exception: [%@]:%@",[ex class], ex); 
     NSLog(@"ex.name:'%@'", ex.name); 
     NSLog(@"ex.reason:'%@'", ex.reason); 
     //Full error includes class pointer address so only care if it starts with this error 
     NSRange range = [ex.reason rangeOfString:@"Pushing the same view controller instance more than once is not supported"]; 

     if ([ex.name isEqualToString:@"NSInvalidArgumentException"] && 
      range.location != NSNotFound) { 
      //view controller already exists in the stack - just pop back to it 
      [self.navController popToViewController:viewController animated:NO]; 
     } else { 
      NSLog(@"ERROR:UNHANDLED EXCEPTION TYPE:%@", ex); 
     } 
    } @finally { 
     //NSLog(@"finally"); 
    } 
    } else { 
    NSLog(@"ERROR:pushViewController: viewController is nil"); 
    } 
} 
+19

Đây là "sửa chữa" các triệu chứng và không phải là nguyên nhân cơ bản. –

+0

Tôi đang gặp vấn đề tương tự, thử thêm thử, bắt khối nhưng nó không bao giờ đi vào khối catch. Tui bỏ lỡ điều gì vậy?? –

3

Điều đó có nghĩa là bạn đang đẩy cùng một đối tượng xem điều khiển để ngăn xếp lại khi nó đã có trong đó.

[self.navigationController pushViewController:viewControllerObj animated:NO]; 

[self.navigationController pushViewController:viewControllerObj animated:NO]; 

kiểm tra nếu ur đẩy bên trong một vòng lặp hoặc nếu u've vô tình đặt mã nhiều hơn một thời gian ..

+1

bên trong vòng lặp. –

0

Một tùy chọn khác mà tôi đã có kinh nghiệm là [MyInboxVC được] không phải là trở về một thể hiện của một đối tượng MyInboxVC. Một dấu hiệu cho biết câu chuyện này sẽ là lỗi nói 'Đẩy cùng một trường hợp bộ điều khiển xem nhiều hơn một lần không được hỗ trợ (notTheInboxVC: 0x9e31660)' tức là. lớp được đẩy nhiều lần không phải là MyInboxVC mong đợi (một phần từ MyInboxVC không được cấp phát)

1

Lý do chính cho vấn đề này, rõ ràng là mã đã đẩy trình điều khiển xem được gọi nhiều lần. Điều này có thể xảy ra vì nhiều lý do, sai lầm phổ biến nhất khi một phương thức gọi lại được kích hoạt từ một chuỗi nền, trong đó phương thức này có thể được thực hiện nhiều lần trong khi nó vẫn đang đẩy trình điều khiển xem. Ví dụ: Gọi api dịch vụ trên chuỗi nền khi chạm vào nút, nút này sẽ cho phép bạn nhấn nút nhiều lần và do đó cuộc gọi lại đẩy bộ điều khiển chế độ xem được gọi nhiều lần. Giải pháp @Melvin và @Sam hợp lệ miễn là bạn không muốn khắc phục vấn đề ban đầu bằng cách không đẩy nhiều hơn một lần.

3

Bạn đang thực hiện điều này như là một phần của sự khác biệt? Nếu bạn đang có, không cần phải đẩy một VC vào Navigation Controller của bạn bởi vì segue sẽ làm điều đó rồi. Đó là lý do tại sao lỗi của bạn đang xảy ra - bạn đang đẩy một VC đã có trên ngăn xếp của NavController.

+0

Đây là câu trả lời đúng nhờ rất nhiều người đàn ông: D –

-1

[devNavController pushViewController: inboxVC hoạt ảnh: NO]; Đặt hoạt ảnh là NO

0

Điều này đã xảy ra với tôi khi nhấp vào nút thanh xảy ra quá nhanh và khó tái tạo, trừ khi bạn sử dụng nút bấm. Sau đây cố định nó bằng cách vô hiệu hóa các nút, bắt đầu đẩy nav, sau đó cho phép các nút trên thread chính (vì nó sẽ được gọi là sau khi hình ảnh động từ đẩy xảy ra).

- (void)showMore 
{ 
    self.navigationItem.leftBarButtonItem.enabled = NO; 
    [self.navigationController pushViewController:moreVC animated:YES]; 
    [self.navigationItem.leftBarButtonItem performSelectorOnMainThread:@selector(setEnabled:) withObject:@(YES) waitUntilDone:NO]; 
} 
0

Đảm bảo bạn không thêm bộ điều khiển chế độ xem hai lần trong ngăn điều hướng. Ví dụ -

navController = [[UINavigationController alloc] initWithRootViewController: self.mainViewC];
self.window.rootViewController = navController; [self.window makeKeyAndVisible];
[navController pushViewController: self.mainViewC hoạt ảnh: NO];

Trong trường hợp này mainViewC đã được thêm vào ngăn xếp khi initWithRootViewController được viết. Không cần pushViewController nữa.

0

tôi khắc phục sự cố tương tự (Swift 4) với IB segue sử dụng:

override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool { 
    return navigationController?.topViewController is MainController ? true : false 
} 
Các vấn đề liên quan