2013-03-26 22 views
8

Tôi đang gặp phải một sự cố rất lạ, đây là backtrace.Lạ tai nạn khi loại bỏ bộ điều khiển xem, bố cục tự động để đổ lỗi?

* thread #1: tid = 0x2403, 0x3379516c CoreFoundation`CFHash + 8, stop reason = EXC_BREAKPOINT (code=EXC_ARM_BREAKPOINT, subcode=0xdefe) 
    frame #0: 0x3379516c CoreFoundation`CFHash + 8 
    frame #1: 0x33797a9c CoreFoundation`CFBasicHashRemoveValue + 1408 
    frame #2: 0x337974ee CoreFoundation`CFDictionaryRemoveValue + 166 
    frame #3: 0x3420988e Foundation`-[NSISEngine removeConstraintWithMarker:] + 562 
    frame #4: 0x34211dbe Foundation`-[NSLayoutConstraint _removeFromEngine:] + 230 
    frame #5: 0x35a954ec UIKit`-[UIView(UIConstraintBasedLayout) _layoutEngine_willRemoveLayoutConstraint:] + 44 
    frame #6: 0x358488fc UIKit`__48-[UIScrollView _setAutomaticContentConstraints:]_block_invoke_0 + 148 
    frame #7: 0x34208882 Foundation`-[NSISEngine withAutomaticOptimizationDisabled:] + 166 
    frame #8: 0x35848838 UIKit`-[UIScrollView _setAutomaticContentConstraints:] + 116 
    frame #9: 0x35848e6c UIKit`-[UIScrollView _rememberDependentConstraint:] + 112 
    frame #10: 0x35a9e3ae UIKit`___updateViewDependenciesForConstraint_block_invoke_0 + 30 
    frame #11: 0x35a954ba UIKit`_updateViewDependenciesForConstraint + 202 
    frame #12: 0x35a953da UIKit`-[UIView(UIConstraintBasedLayout) _layoutEngine_didAddLayoutConstraint:roundingAdjustment:mutuallyExclusiveConstraints:] + 154 
    frame #13: 0x35a95534 UIKit`-[UIView(UIConstraintBasedLayout) _tryToAddConstraintWithoutUpdatingConstraintsArray:roundingAdjustment:mutuallyExclusiveConstraints:] + 36 
    frame #14: 0x3567c2e0 UIKit`-[UIView(Internal) _didMoveFromWindow:toWindow:] + 376 
    frame #15: 0x356d34fe UIKit`-[UIScrollView _didMoveFromWindow:toWindow:] + 50 
    frame #16: 0x3567c5c6 UIKit`-[UIView(Internal) _didMoveFromWindow:toWindow:] + 1118 
    frame #17: 0x35676e52 UIKit`-[UIView(Hierarchy) _postMovedFromSuperview:] + 138 
    frame #18: 0x3565e7dc UIKit`-[UIView(Internal) _addSubview:positioned:relativeTo:] + 1300 
    frame #19: 0x3565e2c2 UIKit`-[UIView(Hierarchy) addSubview:] + 30 
    frame #20: 0x356f68e8 UIKit`-[UITransitionView transition:fromView:toView:removeFromView:] + 972 
    frame #21: 0x35937618 UIKit`__91-[UIWindowController transition:fromViewController:toViewController:target:didEndSelector:]_block_invoke_0238 + 388 
    frame #22: 0x357499b8 UIKit`-[UIWindowController transition:fromViewController:toViewController:target:didEndSelector:] + 4824 
    frame #23: 0x357b9814 UIKit`-[UIViewController _dismissViewControllerWithTransition:from:completion:] + 1708 
    frame #24: 0x357057c4 UIKit`-[UIViewController dismissViewControllerWithTransition:completion:] + 912 
    frame #25: 0x000ccd40 Capture`-[INFTagSearchViewController cancelButtonTouched:](self=0x1f09ed50, _cmd=0x001b9d5f, sender=0x1e0265c0) + 76 at INFTagSearchViewController.m:48 
    frame #26: 0x357470c4 UIKit`-[UIApplication sendAction:to:from:forEvent:] + 72 
    frame #27: 0x35747076 UIKit`-[UIApplication sendAction:toTarget:fromSender:forEvent:] + 30 
    frame #28: 0x35747054 UIKit`-[UIControl sendAction:to:forEvent:] + 44 
    frame #29: 0x3574690a UIKit`-[UIControl(Internal) _sendActionsForEvents:withEvent:] + 502 
    frame #30: 0x35746e00 UIKit`-[UIControl touchesEnded:withEvent:] + 488 
    frame #31: 0x3566f5f0 UIKit`-[UIWindow _sendTouchesForEvent:] + 524 
    frame #32: 0x3565c800 UIKit`-[UIApplication sendEvent:] + 380 
    frame #33: 0x3565c11a UIKit`_UIApplicationHandleEvent + 6154 
    frame #34: 0x373655a2 GraphicsServices`_PurpleEventCallback + 590 
    frame #35: 0x373651d2 GraphicsServices`PurpleEventCallback + 34 
    frame #36: 0x33829172 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 34 
    frame #37: 0x33829116 CoreFoundation`__CFRunLoopDoSource1 + 138 
    frame #38: 0x33827f98 CoreFoundation`__CFRunLoopRun + 1384 
    frame #39: 0x3379aebc CoreFoundation`CFRunLoopRunSpecific + 356 
    frame #40: 0x3379ad48 CoreFoundation`CFRunLoopRunInMode + 104 
    frame #41: 0x373642ea GraphicsServices`GSEventRunModal + 74 
    frame #42: 0x356b0300 UIKit`UIApplicationMain + 1120 
    frame #43: 0x000a297c Capture`main(argc=1, argv=0x2fd60cfc) + 116 at main.m:16 
    frame #44: 0x3bb2bb20 libdyld.dylib`start + 4 

Bạn sẽ thấy khung 25 là cuộc gọi duy nhất mà mã của tôi tạo và nó là cancelButtonTouched.

- (IBAction)cancelButtonTouched:(id)sender { 
    [self dismissViewControllerAnimated:YES completion:nil]; 
} 

Tôi đang thua lỗ về những gì đang diễn ra, tôi chưa từng gặp vấn đề như thế này trước đây, dựa trên hệ thống gọi nó là vấn đề bố cục tự động. Tôi đã xác minh rằng viewWillApper được gọi trên bộ điều khiển hiển thị xem trước khi sự cố xảy ra, vì vậy tôi giả định nó là một phát hành trong khi bố trí của khung nhìn trình bày.

Bất kỳ ý tưởng nào về cách thu hẹp sự cố này xuống một đường dẫn bố cục cụ thể? Hoặc bất kỳ ý tưởng nào khác?

Điều này có thể tái tạo trên một số thiết bị, ở những nơi khác, hiếm khi xảy ra. Vì vậy, nó là gián đoạn.

Cập nhật

Ảnh chụp màn hình của breakpoint.

enter image description here

Cập nhật 2

Vì vậy, nó chắc chắn là một vấn đề với sa thải đến presentingViewController, gạt bỏ hai cấp độ sâu ([self.presentingViewController.presentingViewController dismissViewControllerAnimated:YES completion:nil]) hoạt động tốt, nhưng rõ ràng không phải là kết quả mong muốn, tôi chỉ muốn quay trở lại 1 cấp độ. Điều này càng khiến tôi tin rằng có một vấn đề "tái bố trí" ra ngoài tầm nhìn.

+0

Bạn có điểm dừng đối với ngoại lệ Mục tiêu-C không? Nếu vậy, điều gì sẽ xảy ra nếu bạn tiếp tục thực hiện sau khi mã này được nhấn? Autolayout ném ngoại lệ khi nó phá vỡ ràng buộc, nhưng không đăng nhập lỗi thực sự cho đến sau khi ngoại lệ được ném. – frozendevil

+0

Đúng vậy, nhưng nó dừng lại ở cùng một điểm có hoặc không có điểm ngắt được bật. Tiếp tục không làm gì, chỉ tiếp tục chạm vào cùng một điểm. Đính kèm một ảnh chụp màn hình của nơi nó đang phá vỡ, ngăn xếp là giống như được đăng trong văn bản. –

+0

Ngoài ra, tôi không thấy thông báo gỡ rối tự động bố cục tự động liên quan đến các ràng buộc không mong muốn, v.v. –

Trả lời

4

Dựa trên ý tưởng của Carl Lindberg tôi đã chuẩn bị và sử dụng các loại iOS sau và tôi không có vụ tai nạn nữa:

UIView + AddSubviewWithRemovingFromParent.h

#import <UIKit/UIKit.h> 

@interface UIView (AddSubviewWithRemovingFromParent) 

- (void)addSubviewWithRemovingFromParent:(UIView *)view; 

@end 

UIView + AddSubviewWithRemovingFromParent.m

#import "UIView+AddSubviewWithRemovingFromParent.h" 

@implementation UIView (AddSubviewWithRemovingFromParent) 

- (void)addSubviewWithRemovingFromParent:(UIView *)view { 
    if (view.superview != nil) { 
     [view removeFromSuperview]; 
    } 
    [self addSubview:view]; 
} 

@end 

bây giờ bạn có thể sử dụng phương pháp addSubviewWithRemovingFromParent để thêm subview thay vì phương pháp addSubview như thế này:

UITableViewCell *cell = [[UITableViewCell alloc] init]; 
[cell.contentView addSubviewWithRemovingFromParent:<viewToAdd>]; 

Nói tóm lại:

  1. tìm thấy tất cả tài liệu tham khảo của addSubview trong bộ điều khiển của bạn nơi ứng dụng bị lỗi
  2. nhập danh mục UIView + AddSubviewWithRemovingF romParent.h
  3. sử dụng phương pháp addSubviewWithRemovingFromParent thay vì addSubview
+0

Bạn có thể có thể kiểm tra xem nếu xem. superview == tự, và nếu đó là trường hợp, chỉ cần gọi [self bringSubviewToFront: view] thay vì xóa sau đó thêm lại. Cùng một kết quả và nên hiệu quả hơn. Thêm/xóa các bản xem trước có thể kích hoạt một loạt các nội dung khác mà bạn có thể hoặc không muốn. –

+0

Xin chào, trong trường hợp của tôi, bạn cần xóa và thêm lại. Vấn đề là, UITableViewCell được khởi tạo nhiều lần hơn, bởi vì 'reloadDataTable' được gọi nhiều lần hơn. Do đó, subview đã được thêm vào nhiều hơn một view (nó có hai loại cha mẹ). Hệ thống iOS 7 đã có thể xóa chế độ xem khỏi bố mẹ gốc, iOS 6 thì không.Bạn có thể nói bây giờ, ok, bạn không nên thêm một chế độ xem vào nhiều hơn một phụ huynh. Có, tôi đồng ý, đó là cách để đi, nhưng hệ thống nên có khả năng này (xử lý "nhiều cha mẹ" tình hình) "ra khỏi hộp" tôi nghĩ. – ljboy

+0

Nếu bạn thêm một chế độ xem phụ hiện là một phần của phân cấp chế độ xem khác, thì có, nó sẽ được tự động di chuyển ra khỏi chế độ xem đó. Có lẽ trong bố cục tự động iOS6, phần đó không được xử lý sạch. Vì vậy, trong trường hợp của bạn, có, bạn sẽ cần phải loại bỏ từ superview hiện tại trước khi thêm vào chính mình. Nhưng nếu người giám sát hiện tại đã là chính bạn, sẽ không cần phải xóa rồi thêm lại. Đó có thể là đủ phổ biến để kiểm tra trong mã của bạn. Nhưng nó cũng tốt để biết rằng iOS7 xử lý này (tôi nghi ngờ nó có thể), vì vậy mã trên chỉ có thể cần thiết trên iOS6. Cảm ơn vì điều đó. –

7

Tôi dường như nhớ một cái gì đó như thế này, mặc dù không chắc chắn đó là điều tương tự. Trong trường hợp của tôi, nó được gây ra bằng cách gọi addSubview: (hoặc insertSubview: ...) với chế độ xem đã là một chế độ xem phụ. Trong khi bình thường tôi nghĩ rằng UIView giao dịch với điều đó, với bố cục tự động có vẻ như có thể một số thông tin liên quan sẽ được thêm vào nơi khác hai lần và có thể xảy ra sự cố khi cố gắng xóa thông tin liên quan đó. Trong trường hợp của tôi, giải pháp là để đảm bảo rằng tôi chỉ thêm các bản xem trước một lần, và sự cố này (hoặc một sự tương tự của tôi) đã biến mất.

+0

Tuyệt vời - đó là nó cho tôi quá. Một cuộc gọi nhanh tới [view removeFromSuperView] đã sắp xếp nó. Thanks @carl :-) – Matthew

0

Tôi đã có/có cùng một vấn đề.
Cùng một vấn đề xảy ra với tôi, khi tôi trình bày hai bộ điều khiển xem một cách tương đối trên nhau và muốn quay lại đầu tiên. Vô hiệu hóa tính năng tự động hoàn thành cho chế độ xem được trình bày đầu tiên chỉ giải quyết vấn đề cho tôi.
Trong trường hợp của bạn self.presentingviewcontroller
Rất tiếc, tôi không thể thu hẹp thêm nữa.

+0

Rất tiếc, có vẻ như bạn không sử dụng Bảng phân cảnh? Từ những gì tôi hiểu nếu bạn sử dụng một Storyboard mỗi cảnh/xem trong đó là tự động bố trí hay không .... Có lẽ Xcode 5 với tự động bố trí cải tiến sẽ tiết lộ/sửa chữa vấn đề thực sự –

1

Trong trường hợp của tôi sụp đổ này đã xảy ra khi tôi đã có một bộ điều khiển xem trong một kịch bản nhưng nạp nội dung quan điểm từ một NIB với bộ điều khiển xem giống như các tập tin chủ nhân. Điều này thường hoạt động tốt, nhưng tôi đã có các cửa hàng view thiết lập trong cả storyboard và NIB, mà kích hoạt iOS6 "thêm subview hai lần" lỗi. Bằng cách xóa các cửa hàng xem trong NIB tất cả đã được cố định.

Các vấn đề liên quan