iOS端如何屏蔽控制台大量的‘ignoring invalid setDrawableSize’日志?
解决CAMetalLayer无效尺寸日志刷屏问题
临时快速屏蔽(调试用)
- 打开Xcode的Scheme编辑窗口,在「Arguments Passed On Launch」里添加
OS_ACTIVITY_MODE=disable,但这会关掉所有系统日志,适合临时排查其他问题时用。 - 更精准的过滤:在Xcode控制台的搜索框输入
-CAMetalLayer ignoring invalid setDrawableSize,直接隐藏这条重复日志,不影响其他输出。
从根源解决(推荐)
既然你没直接用Metal,大概率是第三方库(比如Lottie)的锅,试试这些操作:
- 升级Lottie:旧版本的Lottie在初始化动画时可能会错误地给CAMetalLayer设置0尺寸,更到最新稳定版基本能解决这个问题。
- 检查视图时机:确保加载第三方动画的视图,是在尺寸确定之后(比如
viewDidLayoutSubviews或layoutSubviews方法里)才初始化动画,别在视图还没布局好、尺寸为0的时候就启动。 - 切换渲染引擎:如果Lottie默认用Metal渲染,强制改成Core Animation。比如初始化Lottie的AnimationView时,设置
animationView.renderingEngine = .coreAnimation,这样就不会触发Metal相关的日志了。
自定义日志拦截(终极方案)
如果上面的方法都不管用,可以通过Hook系统日志函数来精准拦截这条日志:
#import <asl.h> #import <dlfcn.h> #import "fishhook.h" static void (*original_asl_log)(asl_object_t, asl_object_t, uint32_t, const char *, ...); void custom_asl_log(asl_object_t msg, asl_object_t s, uint32_t level, const char *format, ...) { va_list args; va_start(args, format); char logBuffer[1024]; vsnprintf(logBuffer, sizeof(logBuffer), format, args); va_end(args); // 跳过目标日志 if (!strstr(logBuffer, "CAMetalLayer ignoring invalid setDrawableSize")) { original_asl_log(msg, s, level, format, args); } } // 在AppDelegate的didFinishLaunchingWithOptions里调用 void setupLogFilter() { struct rebinding aslLogRebind = { "asl_log", custom_asl_log, (void *)&original_asl_log }; rebind_symbols((struct rebinding[1]){aslLogRebind}, 1); }
注意:这个方法需要依赖fishhook库,而且要注意App Store审核的风险,建议只在调试阶段使用,上线前记得移除。
内容的提问来源于stack exchange,提问作者Anton Tropashko
相关产品推荐
相关产品推荐

