ldi*_*ual 16 ios autolayout nslayoutconstraint swift
是否有可能在生产中捕获自动布局约束模糊 - 相当于UIViewAlertForUnsatisfiableConstraints
断点,但对于生产应用程序?
我的目标是添加一个全局处理程序,将此类错误报告给日志记录系统.
符号UIViewAlertForUnsatisfiableConstraints
实际上是一个函数:
_UIViewAlertForUnsatisfiableConstraints(NSLayoutConstraint* unsatisfiableConstraint, NSArray<NSLayoutConstraint*>* allConstraints)
.
它是私人的,所以你无法取代它.
但它是从私人方法调用的-[UIView engine:willBreakConstraint:dueToMutuallyExclusiveConstraints:]
,可以调整.此方法大致包含以下内容:
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果我从这篇文章中理解正确,__UIConstraintBasedLayoutVisualizeMutuallyExclusiveConstraints
将始终在iOS上返回NO,所以您需要做的就是检查_isUnsatisfiableConstraintsLoggingSuspended
调用的私有bool属性然后调用原始方法.
这是结果代码示例:
#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
Run Code Online (Sandbox Code Playgroud)
它适用于iOS 8.2/9/10(它在iOS 8.1中不起作用,所以要小心),但我无法保证.此外,它还可以捕获系统组件中的约束问题,例如键盘/视频播放器/等.此代码很脆弱(它可能导致任何系统版本更新崩溃,参数更改等),我不建议在生产中使用它(猜测它甚至不会通过自动审查过程).你有最后一个字,但是你被警告了.
但是我认为您可以在内部/外部测试人员的构建中使用它来修复生产前的autolayout中的错误.
注意到您正在使用swift:您可以使用桥接头文件将此代码添加到swift项目中.
归档时间: |
|
查看次数: |
977 次 |
最近记录: |