当我使用xcode 8在ios 10中运行我的应用程序时,我在调试控制台中收到以下消息,并且通过UI获取冻结,任何人都可以知道为什么会发生这种情况
ERROR
/BuildRoot/Library/Caches/com.apple.xbs/Sources/VectorKit/VectorKit-1228.30.7.17.9/GeoGL/GeoGL/GLCoreContext.cpp
1763: InfoLog SolidRibbonShader: ERROR
/BuildRoot/Library/Caches/com.apple.xbs/Sources/VectorKit/VectorKit-1228.30.7.17.9/GeoGL/GeoGL/GLCoreContext.cpp
1764: WARNING: Output of vertex shader 'v_gradient' not read by
fragment shader
答案 0 :(得分:49)
<强>答案强>
在Xcode中可能会收到此警告的一种情况是使用使用着色器的应用程序,例如带有MKMapView
的 Maps 应用程序。您将发现地图视图在具有真实硬件/本机操作系统的真实设备上没有该警告的情况下按预期工作。
在SIM卡中,SolidRibbonShader
片段着色器无法读取v_gradient
顶点着色器的输出,因为它可能是因为它&#39;处于测试阶段或Xcode版本与SIM版本之间可能存在不兼容性。然而,着色器在真实设备上被识别。
<强>解释强>
这些着色器属于 OpenGL渲染管道。渲染管道是OpenGL渲染对象时所采用的步骤序列。
渲染管道负责应用纹理,将顶点转换为右坐标系以及在屏幕上显示字符等内容。
这个渠道有六个阶段。
最后,您的设备屏幕上会出现一个图像。这六个阶段称为 OpenGL渲染管道,所有用于渲染的数据都必须通过它。
什么是着色器?
着色器是由您开发的一个小程序,位于GPU中。着色器使用称为 OpenGL着色语言(GLSL)的特殊图形语言编写。
着色器取代了OpenGL渲染管道中的两个重要阶段: Per-Vertex Processing 和 Per-Fragment Processing 阶段。这两个阶段中的每个阶段都有一个着色器。
Vertex Shader
的最终目标是提供网格顶点到渲染管道的最终转换。 Fragment shader
的目标是为每个前往帧缓冲区的像素提供着色和纹理数据。
Vertex shaders
将三角形的顶点从局部模型坐标系转换为屏幕位置。 Fragment shaders
计算屏幕上栅格化的三角形内像素的颜色。
单独的着色器对象加速编译和链接
许多OpenGL ES应用程序使用多个顶点和片段着色器,使用不同的重用相同的片段着色器通常很有用>顶点着色器,反之亦然。因为核心OpenGL ES规范要求在单个着色器程序中将顶点和片段着色器链接在一起,所以混合和匹配着色器会导致大量程序,从而增加初始化应用程序时的总着色器编译和链接时间。
答案 1 :(得分:3)
更新:现在Xcode9 / iOS11上的问题已经消失。
首先,无论是在调试模式还是在发布模式下,只有在 Xcode 8 上运行且仅在 iOS 10 (当前为10.0.2)时才会出现冻结问题。当应用程序通过App Store或第三方ad hoc分发系统分发时,MKMapView似乎很好。您看到的警告可能与问题有关,也可能与此无关,我不知道。
我发现有问题的代码是在MKMapView的析构函数中,你对地图视图对象的处理方式或配置方式并不重要,即仅仅调用< / p>
[MKMapView new];
代码中的任何位置都会冻结应用。主线程挂在信号量上,并不清楚原因。
我尝试过的一件事就是在一个单独的线程中销毁地图视图对象,但这并没有帮助。最终我决定至少在DEBUG版本中保留我的地图对象。
注意:这是一个非常糟糕的解决方法,但至少它可以帮助您调试应用程序而不会冻结。保留这些对象意味着每次使用地图创建视图控制器时,内存使用量将增加约45-50MB。
所以,让我们说如果你有一个属性mapView
,那么你可以在视图控制器的dealloc中执行此操作:
- (void)dealloc
{
#if DEBUG
// Xcode8/iOS10 MKMapView bug workaround
static NSMutableArray* unusedObjects;
if (!unusedObjects)
unusedObjects = [NSMutableArray new];
[unusedObjects addObject:_mapView];
#endif
}