- (void)flushMessageQueue:(NSString *)messageQueueString{ if (messageQueueString == nil || messageQueueString.length == 0) { NSLog(@"WebViewJavascriptBridge: WARNING: ObjC got nil while fetching the message queue JSON from webview. This can happen if the WebViewJavascriptBridge JS is not currently present in the webview, e.g if the webview just loaded a new page."); return; }
/* Unlike the other properties, the constant may be modified after constraint creation. Setting the constant on an existing constraint performs much better than removing the constraint and adding a new one that's just like the old but for having a new constant. */ @propertyCGFloat constant;
/* The receiver may be activated or deactivated by manipulating this property. Only active constraints affect the calculated layout. Attempting to activate a constraint whose items have no common ancestor will cause an exception to be thrown. Defaults to NO for newly created constraints. */ @property (getter=isActive) BOOL active NS_AVAILABLE(10_10, 8_0);
// other code MASLayoutConstraint *existingConstraint = nil; if (self.updateExisting) { //如果是update,则去匹配对应的existingConstraint existingConstraint = [self layoutConstraintSimilarTo:layoutConstraint]; } if (existingConstraint) { //找到了existingConstraint,最终也只更新了existingConstraint.constant // just update the constant existingConstraint.constant = layoutConstraint.constant; self.layoutConstraint = existingConstraint; } else { //没有找到existingConstraint,添加一个新的约束 [self.installedView addConstraint:layoutConstraint]; self.layoutConstraint = layoutConstraint; [firstLayoutItem.mas_installedConstraints addObject:self]; } }
// 除了constant,其它都一样的约束是Similar约束 - (MASLayoutConstraint *)layoutConstraintSimilarTo:(MASLayoutConstraint *)layoutConstraint { // check if any constraints are the same apart from the only mutable property constant
// go through constraints in reverse as we do not want to match auto-resizing or interface builder constraints // and they are likely to be added first. for (NSLayoutConstraint *existingConstraint inself.installedView.constraints.reverseObjectEnumerator) { if (![existingConstraint isKindOfClass:MASLayoutConstraint.class]) continue; if (existingConstraint.firstItem != layoutConstraint.firstItem) continue; if (existingConstraint.secondItem != layoutConstraint.secondItem) continue; if (existingConstraint.firstAttribute != layoutConstraint.firstAttribute) continue; if (existingConstraint.secondAttribute != layoutConstraint.secondAttribute) continue; if (existingConstraint.relation != layoutConstraint.relation) continue; if (existingConstraint.multiplier != layoutConstraint.multiplier) continue; if (existingConstraint.priority != layoutConstraint.priority) continue;
2016-08-03 18:49:13.110 layout[47924:2886276] Unable to simultaneously satisfy constraints. Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. ( "<MASLayoutConstraint:0x7ffecb632470 UIButton:0x7ffecb4f28e0.width == 100>", "<MASLayoutConstraint:0x7ffecb637550 UILabel:0x7ffecb637030.width == UIButton:0x7ffecb4f28e0.width>", "<MASLayoutConstraint:0x7ffecb71fc10 UILabel:0x7ffecb637030.width == 200>" )
Will attempt to recover by breaking constraint <MASLayoutConstraint:0x7ffecb71fc10 UILabel:0x7ffecb637030.width == 200>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger. The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful. 2016-08-03 18:49:13.111 layout[47924:2886276] Unable to simultaneously satisfy constraints. Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. ( "<MASLayoutConstraint:0x7ffecb612bc0 UIButton:0x7ffecb4f28e0.height == 33>", "<MASLayoutConstraint:0x7ffecb625300 UILabel:0x7ffecb637030.height == UIButton:0x7ffecb4f28e0.height>", "<MASLayoutConstraint:0x7ffecb486f10 UILabel:0x7ffecb637030.height == 100>" )
Will attempt to recover by breaking constraint <MASLayoutConstraint:0x7ffecb486f10 UILabel:0x7ffecb637030.height == 100>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger. The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
Removes the object at index .
To fill the gap, all elements beyond index are moved by subtracting 1 from their index.
Important:Important
Raises an exception NSRangeException if index is beyond the end of the array.
删除指定NSMutableArray中指定index的对象,注意index不能越界。
removeObject:
Removes all occurrences in the array of a given object.
This method uses indexOfObject: to locate matches and then removes them by using removeObjectAtIndex:. Thus, matches are determined on the basis of an object’s response to the isEqual: message. If the array does not contain anObject, the method has no effect (although it does incur the overhead of searching the contents).
- (void)removeObjectsUseFor { NSMutableArray *contents = [@[@"how", @"to", @"remove", @"remove", @"object"] mutableCopy]; for (NSInteger i = 0; i != contents.count; ++i) { NSString *var = contents[i]; if ([var isEqualToString:@"remove"]) { [contents removeObjectAtIndex:i]; } } NSLog(@"%@", contents); }
输出:
1 2 3 4 5 6
2016-07-31 21:19:59.615 RemoveObject[5886:315162] ( how, to, remove, object )
2.3 引发崩溃的做法
删除数组中所有的@”remove”
1 2 3 4 5 6 7 8 9 10 11
- (void)removeObjectsUseForIn { NSMutableArray *contents = [@[@"how", @"to", @"remove", @"object"] mutableCopy]; for (NSString *var in contents) { if ([var isEqualToString:@"remove"]) { [contents removeObject:var]; } } NSLog(@"%@", contents); }
输出:崩溃
1
2016-07-31 21:27:40.337 RemoveObject[5915:321407] *** Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <__NSArrayM: 0x7f9388c95580> was mutated while being enumerated.'
不要在for in 循环中删除数组内部对象。
2.4 正确但别扭的做法
删除数组中所有的@”remove”
1 2 3 4 5 6 7 8 9 10 11 12
- (void)removeObjectsReversed { NSMutableArray *contents = [@[@"how", @"to", @"remove", @"remove", @"object"] mutableCopy]; for (NSInteger i = contents.count - 1; i >= 0; --i) { NSString *var = contents[i]; if ([var isEqualToString:@"remove"]) { [contents removeObjectAtIndex:i]; } } NSLog(@"%@", contents); }
输出:
1 2 3 4 5
2016-07-31 21:31:37.655 RemoveObject[5934:325316] ( how, to, object )
The frame is not really a distinct property of the view or layer at all; it is a virtual property, computed from the bounds, position, and transform, and therefore changes when any of those properties are modified. Conversely, changing the frame may affect any or all of those values, as well.
@property (readonly, assign) id firstItem; @property (readonly) NSLayoutAttribute firstAttribute; @property (readonly) NSLayoutRelation relation; @property (readonly, assign) id secondItem; @property (readonly) NSLayoutAttribute secondAttribute; @property (readonly) CGFloat multiplier; /* Unlike the other properties, the constant may be modified after constraint creation. Setting the constant on an existing constraint performs much better than removing the constraint and adding a new one that's just like the old but for having a new constant. */ @propertyCGFloat constant;