2016-12-09 5 views
2

Проблема: При попытке удалить подвью приложение неожиданно появляется.Swift: Crash on removeFromSuperview()

Контекст: У меня есть UICollectionViewCell, который обновляется с помощью объекта модели. Я попытался применить эти методы в prepareForReuse и/или в методе update(model: viewModel).

Примечания: Линия That view's superview: NO SUPERVIEW выкатывает. Я дошел до добавления subview обратно, прежде чем звонить removeFromSuperView(), чтобы убедиться, что в супервисте было какое-то время, и он все равно будет терпеть крах.

Я позже повторно добавляю только что сгенерированные экземпляры класса timelineView после того, как все старые очищены.

Он выходит из строя только после пролистывания около ~ 50-150 клеток

Обновления: Спасибо за ваши отзывы в комментариях. Я не удаляю все виды из ячейки. Только один стек с переменным числом компонентов. Но ваше право об удалении subviews против nil'ing. Мне более любопытно, как такие вещи, как stackView.subviews.first?.removeFromSuperview(), могут терпеть неудачу, поскольку это похоже на относительно безопасный вызов (или я ошибаюсь в этом).

Сначала попробуйте

for subview in stackView.subviews { 
    subview.removeFromSuperview() // Crash 
} 

Второй Попробуйте

let subviews = stackView.subviews 
for subview in subviews { 
    if stackView != nil && subview.superview != nil && subview.responds(to: #selector(removeFromSuperview)) && stackView.superview != nil { 
      stackView.subviews.first?.removeFromSuperview() // Crash 
    } 
} 

Третий Попробуйте

let subviews = stackView.subviews 
for subview in subviews { 
    if stackView != nil && subview.superview != nil && subview.responds(to:#selector(removeFromSuperview)) && stackView.superview != nil { 
     if var firstSubview = stackView.subviews.first { 
      for constraint in firstSubview.constraints { 
       constraint.isActive = false 
      } 
      stackView.removeArrangedSubview(firstSubview) 
      firstSubview.removeFromSuperview() // Crash 
     } 
    } 
} 

Исключение:

2016-12-09 00:56:26.792168 appName[59081:4139912] [LayoutConstraints] View hierarchy unprepared for constraint. 
    Constraint: <NSLayoutConstraint:0x618000490cc0 'UISV-canvas-connection' UIStackView:0x7fe25cd25dd0.bottom == appName.timeLineView:0x7fe25e007890.bottom (active)> 
    Container hierarchy: 
    <UIStackView: 0x7fe25cd25dd0; frame = (0 0; 718 40); opaque = NO; autoresize = RM+BM; layer = <CATransformLayer: 0x6080002295a0>> 
    View not found in container hierarchy: <appName.timeLineView: 0x7fe25e007890; frame = (0 0; 718 40); autoresize = W+H; layer = <CALayer: 0x610000835c40>> 
    That view's superview: NO SUPERVIEW 
2016-12-09 00:58:38.655 appName[59081:4139912] *** Terminating app due to uncaught exception 'NSGenericException', reason: 'Unable to install constraint on view. Does the constraint reference something from outside the subtree of the view? That's illegal. constraint:<NSLayoutConstraint:0x618000490cc0 'UISV-canvas-connection' UIStackView:0x7fe25cd25dd0.bottom == appName.timeLineView:0x7fe25e007890.bottom (active)> view:<UIStackView: 0x7fe25cd25dd0; frame = (0 0; 718 40); opaque = NO; autoresize = RM+BM; layer = <CATransformLayer: 0x6080002295a0>>' 
*** First throw call stack: 
(
    0 CoreFoundation      0x000000010df0434b __exceptionPreprocess + 171 
    1 libobjc.A.dylib      0x000000011215121e objc_exception_throw + 48 
    2 CoreFoundation      0x000000010df6d265 +[NSException raise:format:] + 197 
    3 Foundation       0x000000010f097865 -[NSLayoutConstraint _addToEngine:integralizationAdjustment:mutuallyExclusiveConstraints:] + 200 
    4 Foundation       0x000000010f27c6ed __36-[NSISEngine rebuildFromConstraints]_block_invoke + 208 
    5 Foundation       0x000000010f09dbd0 -[NSISEngine withBehaviors:performModifications:] + 155 
    6 Foundation       0x000000010f27c610 -[NSISEngine rebuildFromConstraints] + 488 
    7 Foundation       0x000000010f0a3e1a -[NSISEngine optimize] + 121 
    8 Foundation       0x000000010f27c883 -[NSISEngine _optimizeIfNotDisabled] + 57 
    9 Foundation       0x000000010f0a4ec3 -[NSISEngine removeConstraintWithMarker:] + 799 
    10 Foundation       0x000000010f09bca8 -[NSLayoutConstraint _removeFromEngine:] + 229 
    11 UIKit        0x00000001112314a0 -[UIView(UIConstraintBasedLayout) _layoutEngine_willRemoveLayoutConstraint:] + 105 
    12 UIKit        0x0000000111231bb1 -[UIView(UIConstraintBasedLayout) nsli_removeConstraint:] + 93 
    13 UIKit        0x0000000111243cef _UIViewRemoveConstraintsMadeDanglyByChangingSuperview + 1016 
    14 UIKit        0x000000011091965a __45-[UIView(Hierarchy) _postMovedFromSuperview:]_block_invoke + 61 
    15 UIKit        0x00000001109195a2 -[UIView(Hierarchy) _postMovedFromSuperview:] + 857 
    16 UIKit        0x000000011091721c __UIViewWasRemovedFromSuperview + 172 
    17 UIKit        0x0000000110916d13 -[UIView(Hierarchy) removeFromSuperview] + 564 
    18 appName       0x0000000109aad884 _TFC10appName22TestCollectionViewCell15prepareForReusefT_T_ + 3380 
    19 appName       0x0000000109aada42 _TToFC10appName22TestCollectionViewCell15prepareForReusefT_T_ + 34 
    20 UIKit        0x00000001111bee14 -[UICollectionView _dequeueReusableViewOfKind:withIdentifier:forIndexPath:viewCategory:] + 561 
    21 UIKit        0x00000001111bf834 -[UICollectionView dequeueReusableCellWithReuseIdentifier:forIndexPath:] + 169 
    22 appName       0x0000000109a83623 _TFC10appName30FlightsViewController14collectionViewfTCSo16UICollectionView13cellForItemAtV10Foundation9IndexPath_CSo20UICollectionViewCell + 339 
    23 appName       0x0000000109a83ca7 _TToFC10appName30FlightsViewController14collectionViewfTCSo16UICollectionView13cellForItemAtV10Foundation9IndexPath_CSo20UICollectionViewCell + 87 
    24 UIKit        0x00000001111aa980 -[UICollectionView _createPreparedCellForItemAtIndexPath:withLayoutAttributes:applyAttributes:isFocused:notify:] + 467 
    25 UIKit        0x00000001111aa7a7 -[UICollectionView _createPreparedCellForItemAtIndexPath:withLayoutAttributes:applyAttributes:] + 35 
    26 UIKit        0x00000001111afc7f -[UICollectionView _updateVisibleCellsNow:] + 4803 
    27 UIKit        0x00000001111b5913 -[UICollectionView layoutSubviews] + 313 
    28 UIKit        0x000000011092cf50 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1237 
    29 QuartzCore       0x00000001102c9cc4 -[CALayer layoutSublayers] + 146 
    30 QuartzCore       0x00000001102bd788 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 366 
    31 QuartzCore       0x00000001102bd606 _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 24 
    32 QuartzCore       0x000000011024b680 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 280 
    33 QuartzCore       0x0000000110278767 _ZN2CA11Transaction6commitEv + 475 
    34 QuartzCore       0x00000001101d3b97 _ZN2CA7Display11DisplayLink14dispatch_itemsEyyy + 611 
    35 CoreFoundation      0x000000010de96964 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 20 
    36 CoreFoundation      0x000000010de965f3 __CFRunLoopDoTimer + 1075 
    37 CoreFoundation      0x000000010de9617a __CFRunLoopDoTimers + 250 
    38 CoreFoundation      0x000000010de8df01 __CFRunLoopRun + 2065 
    39 CoreFoundation      0x000000010de8d494 CFRunLoopRunSpecific + 420 
    40 GraphicsServices     0x00000001144e9a6f GSEventRunModal + 161 
    41 UIKit        0x0000000110868964 UIApplicationMain + 159 
    42 appName       0x0000000109a2ba9f main + 111 
    43 libdyld.dylib      0x00000001133b468d start + 1 
) 

Спасибо

+0

брат проверить ваши сдерживать, когда вы удаляете из супервизора свою проблему ограничения с вашим подсмотром, поэтому его авария –

+0

вы можете просто заменить все, что у вас там есть? удаление subviews в ячейках происходит очень медленно, просто установите этот контент на нуль и сделайте его снова, если вам нужно –

+0

, почему вы удаляете subviews ??? – GeneCode

ответ

0

Если бы подобный вопрос, и я думаю, что я решил только сейчас, будучи очень осторожным при удалении элементов из stackview - вот расширение, которое подводит итог:

extension UIStackView { 

    func safelyRemoveArrangedSubviews() { 

     // Remove all the arranged subviews and save them to an array 
     let removedSubviews = arrangedSubviews.reduce([]) { (sum, next) -> [UIView] in 
      self.removeArrangedSubview(next) 
      return sum + [next] 
     } 

     // Deactive all constraints at once 
     NSLayoutConstraint.deactivate(removedSubviews.flatMap({ $0.constraints })) 

     // Remove the views from self 
     removedSubviews.forEach({ $0.removeFromSuperview() }) 
    } 
}