gpt4 book ai didi

ios - 在生产中捕获 UIViewAlertForUnsatisfiableConstraints

转载 作者:IT王子 更新时间:2023-10-29 05:17:33 25 4
gpt4 key购买 nike

是否有可能在生产中捕获自动布局约束歧义 - 相当于 UIViewAlertForUnsatisfiableConstraints 断点但对于生产应用程序?

我的目标是添加一个全局处理程序,将此类错误报告给日志系统。

最佳答案

符号UIViewAlertForUnsatisfiableConstraints实际上是一个函数:

_UIViewAlertForUnsatisfiableConstraints(NSLayoutConstraint* unsatisfiableConstraint, NSArray<NSLayoutConstraint*>* allConstraints) .

它是私有(private)的,因此您无法替换它。

但它是从私有(private)方法调用的-[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);
}
}
}

如果我从 this article 理解正确的话, __UIConstraintBasedLayoutVisualizeMutuallyExclusiveConstraints在 iOS 上将始终返回 NO,因此您需要做的就是检查名为 _isUnsatisfiableConstraintsLoggingSuspended 的私有(private) 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

它适用于 iOS 8.2/9/10(它不适用于 iOS 8.1,所以要小心),但我不能提供任何保证。此外,它还捕获系统组件中的约束问题,例如键盘/视频播放器等。这段代码很脆弱(它可能导致任何系统版本更新、参数更改等崩溃),我不建议在生产中使用它(猜测它甚至不会通过自动审查过程)。你有最后的发言权,但你被警告了。

但是我认为您可以在内部/外部测试人员的构建中使用它来在生产前修复自动布局中的错误。

注意到您正在使用 swift:您可以使用桥接头文件将此代码添加到您的 swift 项目中。

关于ios - 在生产中捕获 UIViewAlertForUnsatisfiableConstraints,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39168712/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com