web-dev-qa-db-fra.com

AutoLayout: removeFromSuperview / removeConstraints lève une exception et plante brutalement

Nous utilisons les contraintes de disposition automatique de manière sélective, principalement pour positionner les étiquettes par rapport aux éléments de champ modifiables (UITextView, UITextField, généralement). Cependant, depuis l'implémentation de la mise en page automatique pour ces champs, nous voyons une exception désagréable et un plantage chaque fois que nous déchargeons des vues, désallouons, etc. Les exceptions se produisent alors qu'il tente de supprimer les contraintes d'une vue avant de la décharger.

Notre hiérarchie de vues/contrôleurs est la suivante:

UITableViewController (plain style, but with cell appearance to mimic grouped style)
--> UITableViewCell
----> UIViewController (container for editable form)
------> UICollectionViewController (editable form)
--------> UICollectionViewCell
-----------> UIViewController (editable field)
--------------> UILabel (field label)                   **HAS CONSTRAINTS**
--------------> UITextView / UITextField (field value)  **HAS CONSTRAINTS**

Plusieurs fois, lorsque les cellules du tableau de niveau supérieur sont désallouées/remplacées/rechargées, nous voyons une énorme exception, puis nous nous bloquons lors de la tentative de désallocation/déchargement de la hiérarchie des vues.

J'ai tenté d'atténuer le plantage en interceptant l'exception (aucune aide) et également en supprimant de force toutes les contraintes sur la vue affectée et toutes les sous-vues avant la désallocation/déchargement (dans viewWillDisappear:) et cela ne semble pas aider. J'ai même essayé de supprimer ces contraintes une par une pour voir s'il y en a une en particulier qui cause le problème, mais toutes explosent lorsque nous appelons removeConstraint: ou removeConstraints: sur un récipient en vue de sa disparition.

Je suis déconcerté! Voici un extrait de notre exception - environ 3000 lignes ont été coupées, donc si vous en avez besoin de plus, demandez simplement.

Exception while deallocating view: { Rows:
    0x18911270.posErrorMarker == 4 + 1*0x18911270.negError + 1*0x189112f0.marker + -1*0x189113f0.negError + 1*0x189113f0.posErrorMarker + 1*0x18911a60.marker + -0.5*0x1892dae0.negError + 0.5*0x1892dae0.posErrorMarker + 1*0x18951520.negError + -1*0x18951520.posErrorMarker + -0.5*0x18958090.negError + 0.5*0x18958090.posErrorMarker
    0x189112b0.negError == 12 + 1*0x189112b0.posErrorMarker + -1*0x189112f0.marker + 1*0x189113f0.negError + -1*0x189113f0.posErrorMarker + -1*0x18911a60.marker + 1*0x18925530.marker + 0.5*0x1892dae0.negError + -0.5*0x1892dae0.posErrorMarker + 1*0x1893e080.marker + 0.5*0x18958090.negError + -0.5*0x18958090.posErrorMarker + 1*0x18963640.marker
    0x18911370.negError == 9 + -1*0x189112f0.marker + 1*0x18911370.posErrorMarker + 1*0x18925530.marker + 1*0x1892dae0.negError + -1*0x1892dae0.posErrorMarker + 1*0x1893e080.marker + 1*0x18963640.marker
    0x189113b0.slackMarker == 2 + -1*0x189107d0.marker + 1*0x18910b90.negError + -1*0x18910b90.posErrorMarker + 

      ........ EXPLETIVES DELETED .........

   UITableView:0xca2b000.contentHeight == 36 + 1*0xc221c00.marker
   UITableView:0xca2b000.contentWidth == 704 + 1*0xc239470.marker
   UITableView:0xca2b000.minX == 0 + 1*0xc2a23f0.marker + -0.5*0xc2a2590.marker
   UITableView:0xca2b000.minY == 0 + 1*0xc2a25d0.marker + -0.5*0xc2a2630.marker
   UITableViewCellContentView:0x18ab13d0.Height == 174 + 1*0x18abd4f0.marker
   UITableViewCellContentView:0x18ab13d0.Width == 704 + 1*0x18abd470.marker

      ........ EXPLETIVES DELETED .........

    <NSAutoresizingMaskLayoutConstraint:0x18988bc0 h=-&- v=-&- UIView:0x18911e50.midY == UIView:0x1892d0c0.midY>        Marker:0x18988bc0.marker
    <NSAutoresizingMaskLayoutConstraint:0x18994b40 h=-&- v=-&- UIView:0xc4a6fb0.midX == UIView:0xc4b4990.midX>      Marker:0x18994b40.marker
    <NSAutoresizingMaskLayoutConstraint:0x18998480 h=-&- v=-&- UIView:0x18915180.width == UIView:0xc4c5970.width>       Marker:0x18998480.marker
    <NSAutoresizingMaskLayoutConstraint:0x18aae320 h=--& v=--& TapSectionalTableViewCell:0x18a3d270.midX == + 352>      Marker:0x18aae320.marker
    <NSAutoresizingMaskLayoutConstraint:0x18aae410 h=--& v=--& H:[TapSectionalTableViewCell:0x18a3d270(704)]>       Marker:0x18aae410.marker
    <NSAutoresizingMaskLayoutConstraint:0x18aae450 h=--& v=--& TapSectionalTableViewCell:0x18a3d270.midY == + 144>      Marker:0x18aae450.marker

      ........ EXPLETIVES DELETED .........

    <NSAutoresizingMaskLayoutConstraint:0xc2de2f0 h=--& v=--& TapGenericCollectionCell:0xc2ac500.midX == + 499>     Marker:0xc2de2f0.marker
    <NSAutoresizingMaskLayoutConstraint:0xc2de3b0 h=--& v=--& V:[TapGenericCollectionCell:0xc2ac500(34)]>       Marker:0xc2de3b0.marker
    <NSAutoresizingMaskLayoutConstraint:0xc2de430 h=-&- v=-&- UIView:0x18953f80.height == UIView:0xc2acb20.height>      Marker:0xc2de430.marker
    <NSAutoresizingMaskLayoutConstraint:0xc2de520 h=-&- v=-&- UIView:0x18923af0.height == UIView:0xc2ae570.height>      Marker:0xc2de520.marker
    <NSAutoresizingMaskLayoutConstraint:0xc2de560 h=--& v=--& H:[TapGenericCollectionCell:0xc2ac500(280)]>      Marker:0xc2de560.marker

      ........ EXPLETIVES DELETED .........

    <NSContentSizeLayoutConstraint:0xc2f5730 H:[_UIBaselineLayoutStrut:0x18994a30(0)] Hug:250 CompressionResistance:750>        Marker:0xc2f5730.posErrorMarker
    <NSContentSizeLayoutConstraint:0xc2f5730 H:[_UIBaselineLayoutStrut:0x18994a30(0)] Hug:250 CompressionResistance:750>        Marker:0xc2f5730.posErrorMarker
    <NSContentSizeLayoutConstraint:0xc2f5770 V:[_UIBaselineLayoutStrut:0x18994a30(18)] Hug:250 CompressionResistance:750>       Marker:0xc2f5770.posErrorMarker

internal error.  Cannot find an outgoing row head for incoming head UIView:0x189712b0.Width, which should never happen.'
/**** BEGIN Individual Field Controller - This code is from the base individual field controller used in our editable form collection *****/

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.clipsToBounds = YES;
    self.view.opaque = YES;

    CGRect viewFrame = self.view.frame;
    viewFrame.size = [self defaultFieldSize];
    self.view.frame = viewFrame;

    if (self.backgroundColor) {
        self.view.backgroundColor = self.backgroundColor;
    }
    else {
        self.view.backgroundColor = [UIColor whiteColor];
    }
    [self createLabelAndField];

    [self setLabelAndFieldContraints];

    [self.view addConstraints:self.labelValueConstraints];
    [self.view setNeedsUpdateConstraints];
}

- (void)createLabelAndField {
    [self removeLabelAndField];

    UILabel *label = [[UILabel alloc] init];
    label.font = self.labelFont;
    label.textColor = self.labelColor;
    label.lineBreakMode = NSLineBreakByWordWrapping;
    label.textAlignment = NSTextAlignmentLeft;
    label.adjustsFontSizeToFitWidth = NO;
    label.numberOfLines = 0;

    if (self.backgroundColor) {
        label.backgroundColor = self.backgroundColor;
    }
    else {
        label.backgroundColor = [UIColor whiteColor];
    }

    [self.view addSubview:label];

    self.label = label;


    /// EXAMPLE valueView initialization from a subclass that handles long text

    TapEditableTextView *textView = [[TapEditableTextView alloc] init];
    if (self.hasLabelOverValue) {
        textView.shouldMimicTextField = NO;
    }
    else {
        textView.shouldMimicTextField = YES;
    }
    textView.delegate = self;
    textView.keyboardType = UIKeyboardTypeDefault;
    textView.font = self.valueFont;
    textView.textColor = self.valueColor;
    textView.textAlignment = NSTextAlignmentLeft;
    textView.normalBackgroundColor = self.backgroundColor;
    textView.editable = NO;
    textView.textLines = self.textLines;

    self.valueTextView = textView;
    self.valueView = textView;
    [self.view addSubview:textView];
}

- (void)removeLabelAndField {
    [self clearConstraints];

    if (self.label) {
        [self.label removeFromSuperview];
        self.label = nil;
    }
    if (self.valueView) {
        [self.valueView removeFromSuperview];
        self.valueView = nil;
    }
}

- (void)clearConstraints {
    if (self.isViewLoaded && self.labelValueConstraints) {
        [self.view removeConstraints:self.labelValueConstraints];
    }
    self.labelValueConstraints = nil;
    self.labelToValueHorizConstraint = nil;
    self.valueWidthConstraint = nil;
}

// This is called in our field's viewDidLoad, after we've created our label and valueView (UITextField, UITextView, etc)
- (void)setLabelAndFieldContraints {
    [self clearConstraints];

    self.labelValueConstraints = [NSMutableArray array];

    self.label.translatesAutoresizingMaskIntoConstraints = NO;
    self.valueView.translatesAutoresizingMaskIntoConstraints = NO;

    NSLayoutConstraint *constraint = nil;

    constraint = [NSLayoutConstraint
                  constraintWithItem:self.label attribute:NSLayoutAttributeLeft
                  relatedBy:NSLayoutRelationEqual
                  toItem:self.view attribute:NSLayoutAttributeLeft
                  multiplier:1.0f constant:self.labelValueGap];
    constraint.priority = UILayoutPriorityRequired;
    [self.labelValueConstraints addObject:constraint];


    constraint = [NSLayoutConstraint
                  constraintWithItem:self.label attribute:NSLayoutAttributeTop
                  relatedBy:NSLayoutRelationEqual
                  toItem:self.view attribute:NSLayoutAttributeTop
                  multiplier:1.0f constant:0];
    constraint.priority = 550;
    [self.labelValueConstraints addObject:constraint];


    constraint = [NSLayoutConstraint
                  constraintWithItem:self.label attribute:NSLayoutAttributeBottom
                  relatedBy:NSLayoutRelationEqual
                  toItem:self.view attribute:NSLayoutAttributeBottom
                  multiplier:1.0f constant:0];
    constraint.priority = 400;
    [self.labelValueConstraints addObject:constraint];


    constraint = [NSLayoutConstraint
                  constraintWithItem:self.valueView attribute:NSLayoutAttributeTop
                  relatedBy:NSLayoutRelationEqual
                  toItem:self.view attribute:NSLayoutAttributeTop
                  multiplier:1.0f constant:0];
    constraint.priority = UILayoutPriorityRequired;
    [self.labelValueConstraints addObject:constraint];


    constraint = [NSLayoutConstraint
                  constraintWithItem:self.valueView attribute:NSLayoutAttributeBottom
                  relatedBy:NSLayoutRelationEqual
                  toItem:self.view attribute:NSLayoutAttributeBottom
                  multiplier:1.0f constant:0];
    constraint.priority = 499;
    [self.labelValueConstraints addObject:constraint];


     constraint = [NSLayoutConstraint
                  constraintWithItem:self.valueView attribute:NSLayoutAttributeRight
                  relatedBy:NSLayoutRelationEqual
                  toItem:self.view attribute:NSLayoutAttributeRight
                  multiplier:1.0f constant: -(kDisclosureWidth + self.labelValueGap) ];
     constraint.priority = 901;
     [self.labelValueConstraints addObject:constraint];


    constraint = [NSLayoutConstraint
                  constraintWithItem:self.valueView attribute:NSLayoutAttributeLeading
                  relatedBy:NSLayoutRelationGreaterThanOrEqual
                  toItem:self.label attribute:NSLayoutAttributeTrailing
                  multiplier:1.0f constant:self.labelValueGap];
    constraint.priority = UILayoutPriorityDefaultHigh + 1;
    [self.labelValueConstraints addObject:constraint];
    self.labelToValueHorizConstraint = constraint;


    constraint = [NSLayoutConstraint
                  constraintWithItem:self.label attribute:NSLayoutAttributeBaseline
                  relatedBy:NSLayoutRelationEqual
                  toItem:self.valueView attribute:NSLayoutAttributeBaseline
                  multiplier:1.0f constant:0.f];
    constraint.priority = 600;
    [self.labelValueConstraints addObject:constraint];


    constraint = [NSLayoutConstraint
                  constraintWithItem:self.valueView attribute:NSLayoutAttributeWidth
                  relatedBy:NSLayoutRelationEqual
                  toItem:self.view attribute:NSLayoutAttributeWidth
                  multiplier:(1.f - self.labelWidthPercentage) constant:0];
    constraint.priority = 305;
    [self.labelValueConstraints addObject:constraint];
    self.valueWidthConstraint = constraint;


    [self setCompressionAndHuggingForLabelView:self.label];
    [self setCompressionAndHuggingForValueView:self.valueView];
}

- (void)setCompressionAndHuggingForLabelView:(UILabel *)labelView {
    if (!labelView) {
        return;
    }
    [labelView setContentCompressionResistancePriority:510 forAxis:UILayoutConstraintAxisHorizontal];
    [labelView setContentCompressionResistancePriority:UILayoutPriorityDefaultHigh forAxis:UILayoutConstraintAxisVertical];
    [labelView setContentHuggingPriority:450 forAxis:UILayoutConstraintAxisHorizontal];
    [labelView setContentHuggingPriority:UILayoutPriorityDefaultHigh forAxis:UILayoutConstraintAxisVertical];
}

- (void)setCompressionAndHuggingForValueView:(UIView *)valueView {
    if (!valueView) {
        return;
    }
    [valueView setContentCompressionResistancePriority:509 forAxis:UILayoutConstraintAxisHorizontal];
    [valueView setContentCompressionResistancePriority:UILayoutPriorityDefaultHigh forAxis:UILayoutConstraintAxisVertical];
    [valueView setContentHuggingPriority:300 forAxis:UILayoutConstraintAxisHorizontal];
    [valueView setContentHuggingPriority:650 forAxis:UILayoutConstraintAxisVertical];
}

/****** END Individual Field Controller ******/
53
Greg Combs

J'ai eu une (longue) conversation avec un ingénieur Apple Apple à propos de cet accident).

Voici les deux causes les plus probables:

  1. Vous avez une contrainte non valide, telle que view1.left = view2.left + 20view2 est inopinément nul ou a un multiplicateur de 0. Assurez-vous de vérifier (et tripler) vos contraintes pour vous assurer qu'elles sont correctes. Voici 2 exemples de contraintes problématiques:

    // The first constraint would be a problem if view2 were nil
    [NSLayoutConstraint constraintWithItem:view1 attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:view2 attribute:NSLayoutAttributeBottom multiplier:1 constant:20];
    // The second constraint is a problem because the 0 multiplier causes view2 to be "lost"
    [NSLayoutConstraint constraintWithItem:view1 attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:view2 attribute:NSLayoutAttributeBottom multiplier:0 constant:5];
    
  2. Vous rencontrez un bogue dans le moteur de mise en page automatique de Foundation interne lié à la perte cumulée de précision en virgule flottante. Lorsque vous êtes tombé en panne, la façon dont vous pouvez savoir que c'est le cas consiste à rechercher dans le (grand) journal des exceptions de la console un très petit (presque zéro) nombre à virgule flottante comme celui-ci:

<505:-7.45058e-08>*PWPlotLegendEntryView:0x600000582be0.Height{id: 34609} +

(Rechercher e- dans la sortie de la console pour trouver des petits nombres comme celui-ci.) Ce nombre (-7.45058e-08 dans ce cas) représente le coefficient à ce moment précis pendant que le moteur interne résout les contraintes. Dans ce cas, le nombre est censé être exactement 0, mais en raison de la façon dont le moteur de disposition automatique effectue des calculs avec des nombres à virgule flottante, il est devenu un nombre négatif extrêmement minuscule à la place, ce qui fait tout exploser. Si vous pouvez trouver un tel nombre dans la sortie, vous savez que vous avez rencontré ce bogue.

Comment pouvez-vous contourner ce problème?

La modification de l'ordre dans lequel vous ajoutez (activez) les contraintes peut finir par modifier l'ordre des calculs dans le moteur interne, ce qui peut entraîner la disparition de ce problème car les calculs sont effectués sans perte de précision problématique.

Ce problème semble se produire plus fréquemment lorsque vous avez modifié la résistance à la compression de contenu ou les priorités de contournement de contenu pour les vues, alors essayez de commenter tout code qui fait cela pour voir si cela provoque l'apparition de ce bogue ou de le réorganiser plus tôt. ou plus tard dans votre code de configuration de contrainte.

Plus de détails sur mon cas spécifique:

J'ai rencontré ce crash sur iOS. Les étapes pour le reproduire étaient assez intéressantes:

  1. Un contrôleur de vue contenant une vue de table a été poussé à l'écran (dans un contrôleur de navigation).
  2. La vue du tableau devait contenir suffisamment de cellules pour qu'elles ne rentrent pas toutes dans la zone visible, puis elle devait être défilée jusqu'à la dernière cellule, puis sauvegarder un peu (probablement, cela entraînait la réutilisation des cellules, ce qui déclenchait le déclenchement). ce problème).
  3. Ensuite, lorsque le contrôleur de vue contenant la vue de table a été extrait de la pile de navigation, immédiatement après la fin de l'animation pop, l'application s'est bloquée au point où la vue du contrôleur de vue a été supprimée de la hiérarchie des vues.

Après beaucoup d'essais et d'erreurs, j'ai pu isoler le problème à une chose spécifique: définir la résistance à la compression de contenu et les priorités d'étreintes pour un UIImageView dans chacune des cellules de la vue tableau. Dans ce cas, la vue de l'image est positionnée à l'aide de la disposition automatique à l'intérieur de la cellule, et pour obtenir la disposition correcte, la vue de l'image doit correspondre exactement à la taille de son contenu intrinsèque (la taille de son image).

C'était le code problématique:

// Inside of the UITableViewCell's updateConstraints method...

[self.imageView setContentCompressionResistancePriority:​UILayoutPriorityRequired forAxis:​UILayoutConstraintAxisHorizontal];        
[self.imageView setContentCompressionResistancePriority:​UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical];       
[self.imageView setContentHuggingPriority:​UILayoutPriorityRequired forAxis:​UILayoutConstraintAxisHorizontal];      
[self.imageView setContentHuggingPriority:​UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical];

Supprimer le code ci-dessus et le remplacer par 2 contraintes (à la priorité requise) pour fixer la largeur et la hauteur de la vue de l'image à la taille de l'image a obtenu le même résultat, mais a évité le plantage. Voici le code de remplacement (en utilisant PureLayout ):

[self.imageView autoSetDimensionsToSize:self.imageView.image.size];

J'ai également constaté que le simple fait de déplacer les 4 lignes problématiques à un endroit différent dans mon code de configuration de contraintes a résolu le problème, probablement parce que cela changeait suffisamment l'ordre des calculs pour éviter la perte de précision problématique.

88
smileyborg

Problème de désallocation - une possibilité

Votre code qui fonctionne avec la mise en page automatique peut bien s'exécuter sur le thread principal, mais l'un des blocs qui s'exécute en arrière-plan et utilise votre vue (peut-être indirectement), peut contenir une référence forte à la vue ou à l'un de ses propriétaires comme le contrôleur de vue (c'est le comportement par défaut des blocs Objective-C). Lorsqu'un tel bloc est exécuté et désalloué sur une file d'attente en arrière-plan, les références fortes qu'il capture sont libérées sur cette même file d'attente et vous pouvez rencontrer un problème bien connu problème de désallocation .

  1. Dans votre contrôleur de vue, assurez-vous que vous utilisez une référence faible à self dans tous les blocs qui n'ont pas besoin d'une référence forte (et peuvent de fonctionner en arrière-plan). Vous pouvez le déclarer comme ceci: __weak typeof(self) weakSelf = self; avant le bloc - et utiliser weakSelf à l'intérieur du bloc.

  2. Il en va de même pour toutes les variables locales qui contiennent des références à vos vues - assurez-vous que leurs valeurs sont capturées en tant que références faibles.

Une autre possibilité

Dans mon travail, j'ai rencontré un problème similaire sur iOS 6 lorsque la vue cachée participait à la mise en page. Suppression de la vue de la hiérarchie (-[UIView removeFromSuperview]) au lieu de définir la propriété hidden sur YES a résolu le problème pour moi.

14
Leon Deriglazov

Le même problème a été résolu en supprimant les contraintes une par une dans IB jusqu'à ce que le crash soit résolu. Cela l'a réduit à la contrainte offensante. J'ai ensuite rétabli ladite contrainte, mais inversé les éléments:

enter image description here

Vous aurez peut-être autant de chance et pourrez résoudre vos problèmes d'AL aussi facilement.

3
Chris

Pour rendre la réponse impressionnante de @ smileyborg plus exploitable:

Cela peut se produire si vous avez des contraintes avec des multiplicateurs qui pourraient souffrir de problèmes de précision en virgule flottante.

Résoudre:

  1. Passez en revue toutes vos contraintes qui ont des multiplicateurs (dans le code de mise en page ou en modifiant manuellement un storyboard/nib et en recherchant multiplier=).
  2. Si le multiplicateur n'est pas une "jolie" puissance de deux flotteurs, tournez-le vers le plus proche (vous pouvez utiliser un calculateur à virgule flottante )

Pour faire facilement 2, entrez le nombre que vous souhaitez et la calculatrice, puis désactivez les bits de précision inférieure dans la mantisse jusqu'à ce que la valeur corresponde à la valeur décimale arrondie en bas de la calculatrice.

2
yonix

Pour toute personne rencontrant ce problème dans n'importe quelle version d'iOS> 8.0, l'état des documents Apple pour utiliser la propriété "active" sur NSLayoutConstraint plutôt que les fonctions removeConstraint/addConstraint sur UIView. Apple Docs addConstraint reference

2
Brandon Chow

Dans mon cas, c'était une contrainte de largeur proportionnelle avec un multiplicateur 8: 9. Je l'ai changé en 7: 9 et cela a fonctionné.

BTW la façon la plus simple de trouver une contrainte est de commencer à supprimer des vues du contrôleur de vue. Faites-le en utilisant un algorithme binaire :) en supprimant la moitié des vues, puis la moitié de la moitié qui fait planter l'application, etc.

1
Borzh

Pour moi, le problème était que je supprimais une contrainte à un moment qui me convenait, après avoir appelé dequeueReusableCellWithReuseIdentifier tout en définissant les propriétés de mon UICollectionViewCell. La solution était d'appeler à la place:

    [_myUICollectionViewCell setNeedsUpdateConstraints];

et remplacer:

    -(void)updateConstraints 

et faire mon bordel là-bas. Semble que vous ne pouvez pas simplement supprimer les contraintes quand vous le souhaitez.

1
troppoli

J'ai eu ce plantage alors qu'il me restait une contrainte manquante en mode wAnyhAny, la correction de ce problème a supprimé l'erreur.

0
Özgür

Je suis juste tombé sur la même erreur sous OSX Mavericks avec une application OSX que je développe, mais contrairement aux autres réponses données, je n'ai certainement aucun autre thread interagissant avec les objets d'interface utilisateur, et la hiérarchie de vues en question est définitivement visible aussi. Je n'utilise pas non plus de blocs. Bizarrement, le problème a disparu lorsque j'ai supprimé une contrainte verticale sur un NSTextField.

FWIW la vue problématique dont la suppression de sa vue d'ensemble provoque l'erreur "erreur interne. Impossible de trouver une tête de ligne sortante pour la tête entrante" est l'un des nombreux contrôles du panneau latéral qui présentent ensemble les propriétés des objets de la vue principale qui peuvent être coupées, copié, créé, etc. Cela signifie que l'utilisateur peut coller de nouveaux objets dans la vue principale assez rapidement, ce qui signifie que les commandes du panneau latéral sont détruites et que de nouvelles sont créées très rapidement également. Bien sûr, avec tout dans le fil principal, cela ne devrait pas faire de différence, mais il semble que ce soit le cas.

La contrainte exacte à l'origine des problèmes était

[self addConstraint: [NSLayoutConstraint constraintWithItem: contrôle attribut: NSLayoutAttributeHeight relatedBy: NSLayoutRelationEqual toItem: autre attribut: NSLayoutAttributeHeight multiplicateur: 1,4 constante: 0,0]];

où contrôle est le NSTextField (modifiable) causant des problèmes, et "autre" est un autre label NSTextField (non modifiable).

0
Andy Southwell

J'ai eu ce problème avec MZFormSheetController pod: https://github.com/m1entus/MZFormSheetController/issues/78

Ce code plante:

[formSheetController.view addSubview:self.sharePanel];
// ...
[self.sharePanel removeFromSuperview]; // <-- CRASHES HERE

Ma solution est très étrange mais ça marche:

[self.sharePanel removeFromSuperview]; // <-- This line helps to avoid crash
[formSheetController.view addSubview:self.sharePanel];
// ...
[self.sharePanel removeFromSuperview];

Et voici la déclaration de propriété sharePanel:

@property (weak, nonatomic) IBOutlet UIView *sharePanel;
0
k06a

Selon Apple Documentation:

Lors du développement pour iOS 8.0 ou version ultérieure, définissez la propriété active de la contrainte sur YES au lieu d'appeler directement la méthode addConstraint :. La propriété active ajoute et supprime automatiquement la contrainte de la vue correcte.

Dans mon cas, j'ai dû modifier la contrainte de largeur

for var constraint in self.navigationBar.constraints {
            if constraint.identifier == "theProgressWidth" {
                let sizeWidth = self.navigationBar.frame.size.width
                constraint = NSLayoutConstraint(item: progress!, attribute: .Width, relatedBy: .Equal, toItem: self.navigationBar, attribute: .Width, multiplier: ((sizeWidth * (level / 100)) / sizeWidth), constant: 0)
                constraint.active = true
            }
        }
0
Arben Pnishi

J'obtiens ce plantage lorsque j'appelle removeConstraints: avec un argument nil.

0
bazik

Comme les autres réponses dans ce fil indiquent que c'est en quelque sorte un problème de mise en page automatique/contraint invalide, bien qu'il semble être très pointilleux sur ce qui se qualifie comme "invalide".

Heureusement, je n'avais pas fait beaucoup de changements depuis mon dernier commit et j'ai pu retrouver les changements offensants. Pour moi, le problème était d'avoir une vue de 10 UIImageView horizontaux avec une largeur égale et un rapport d'aspect fixe de 2: 3.

Le plantage ne semblait se produire qu'après avoir quitté le UIViewController qui contenait cette ligne d'image. Chaque UIImageView a été défini sur UIViewContentModeScaleAspectFill. La suppression de ce changement de mode de contenu (qui a été effectuée avant la définition des UIImage) a semblé résoudre mon problème mais n'était pas une solution acceptable. J'ai fini par supprimer la restriction de rapport d'aspect et à utiliser simplement une largeur et une hauteur fixes pour chaque image.

Pourquoi cela plantait mon application, je ne sais pas ... Le crash pourrait également SEULEMENT être reproduit sur un iPhone 4s exécutant iOS 7.1.2. J'ai essayé de reproduire le même crash sur un simulateur iPhone 4s exécutant iOS 9.1 sans succès. Il ne planterait pas non plus lors de l'exécution sur un iPhone 5 physique exécutant iOS 9.1.

J'espère que cela aide quelqu'un

0
alexgophermix