実際シンボルUIViewAlertForUnsatisfiableConstraints
関数です。
これはプライベートなので置き換えることはできません。
しかし、これはプライベートメソッド-[UIView engine:willBreakConstraint:dueToMutuallyExclusiveConstraints:]
から呼び出され、スイープすることができます。このメソッドは、およそこのコンテンツを持っている:私はthis articleから正しく理解していれば
void -[UIView engine:willBreakConstraint:dueToMutuallyExclusiveConstraints:] {
if ([self _isUnsatisfiableConstraintsLoggingSuspended]) {
[self _recordConstraintBrokenWhileUnsatisfiableConstraintsLoggingSuspended:$arg4]; // add constraint to some pool
}
else {
if (__UIConstraintBasedLayoutVisualizeMutuallyExclusiveConstraints) {
// print something in os_log
}
else {
_UIViewAlertForUnsatisfiableConstraints($arg4, $arg5);
}
}
}
、__UIConstraintBasedLayoutVisualizeMutuallyExclusiveConstraints
はいつもあなたがする必要があるすべては_isUnsatisfiableConstraintsLoggingSuspended
と呼ばれるプライベートブールプロパティをチェックして、オリジナルのメソッドを呼び出すことで、iOSの上でNOを返します。
これは、結果コードの例です:
#import <objc/runtime.h>
void SwizzleInstanceMethod(Class classToSwizzle, SEL origSEL, Class myClass, SEL newSEL) {
Method methodToSwizzle = class_getInstanceMethod(classToSwizzle, origSEL);
Method myMethod = class_getInstanceMethod(myClass, newSEL);
class_replaceMethod(classToSwizzle, newSEL, method_getImplementation(methodToSwizzle), method_getTypeEncoding(methodToSwizzle));
class_replaceMethod(classToSwizzle, origSEL, method_getImplementation(myMethod), method_getTypeEncoding(myMethod));
}
@interface InterceptUnsatisfiableConstraints : NSObject
@end
@implementation InterceptUnsatisfiableConstraints
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
SEL willBreakConstantSel = NSSelectorFromString(@"engine:willBreakConstraint:dueToMutuallyExclusiveConstraints:");
SwizzleInstanceMethod([UIView class], willBreakConstantSel, [self class], @selector(pr_engine:willBreakConstraint:dueToMutuallyExclusiveConstraints:));
});
}
- (void)pr_engine:(id)engine willBreakConstraint:(NSLayoutConstraint*)constraint dueToMutuallyExclusiveConstraints:(NSArray<NSLayoutConstraint*>*)layoutConstraints {
BOOL constrainsLoggingSuspended = [[self valueForKey:@"_isUnsatisfiableConstraintsLoggingSuspended"] boolValue];
if (!constrainsLoggingSuspended) {
NSLog(@"_UIViewAlertForUnsatisfiableConstraints would be called on next line, log this event");
}
[self pr_engine:engine willBreakConstraint:constraint dueToMutuallyExclusiveConstraints:layoutConstraints];
}
@end
それはiOSの8.2/9月10日に動作します(これはiOSの8.1で動作するので、気をつけていない)が、私はすべての保証を与えることはできません。 また、キーボード/ビデオプレーヤーなどのシステムコンポーネントの制約の問題を検出します。 このコードは脆弱です(システムバージョンの更新やパラメータの変更などでクラッシュする可能性があります)。プロダクションでは使用しないことをお勧めします(自動審査プロセスにも合格しないと思われます)。あなたは最後の言葉を持っていますが、あなたは警告を受けています。
しかし、私はあなたが生産の前にautolayoutのバグを修正するために内部/外部テスターのためのビルドでそれを使うことができると思います。
swiftを使用していることに気付きました。このコードをブリッジヘッダーファイルを使用して迅速なプロジェクトに追加できます。
これは良い質問です。私が理解しているように、シンボリックなブレークポイントでは、特定のシンボル、メソッド、セレクタを壊すことができます。私はグローバルなC関数 'UIViewAlertForUnsatisfiableConstraints()'を試してみて、それが 'UIView'のインスタンスかクラスメソッドかどうかを見てみましたが、これまで何も見つかりませんでした。 – JAL