我正在尝试将现有的私有属性转换为实例变量。这个问题不是关于我是否应该将其保留为私有财产。我知道属性的优点。但是,就我而言(至少我认为),我不需要它们。
因此,我要转换的私有属性声明如下:
@interface Renderer ()
@property(nonatomic, strong) MTLRenderPassDescriptor* renderPassDescriptor;
@end
然后将其初始化如下:
- (void)createRenderPassDescriptor
{
self.renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor];
if(_scaledWidth > 0 && _scaledHeight > 0)
{
[self createDepthBufferTexture:self.renderPassDescriptor.depthAttachment];
[self createMultiSamplingTexture:self.renderPassDescriptor.colorAttachments[0]];
}
}
- (void)createMultiSamplingTexture:(MTLRenderPassColorAttachmentDescriptor*)colorAttachmentDescriptor
{
MTLTextureDescriptor* multisamplingTextureDescriptor = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatBGRA8Unorm
width:(NSUInteger)_scaledWidth
height:(NSUInteger)_scaledHeight
mipmapped:FALSE];
multisamplingTextureDescriptor.textureType = MTLTextureType2DMultisample;
multisamplingTextureDescriptor.usage = MTLTextureUsageRenderTarget;
multisamplingTextureDescriptor.storageMode = MTLStorageModePrivate;
multisamplingTextureDescriptor.resourceOptions = MTLResourceStorageModePrivate;
multisamplingTextureDescriptor.sampleCount = _multisampleAntiAliasingCount;
colorAttachmentDescriptor.texture = [self.device newTextureWithDescriptor:multisamplingTextureDescriptor];
colorAttachmentDescriptor.loadAction = MTLLoadActionClear;
colorAttachmentDescriptor.storeAction = MTLStoreActionMultisampleResolve;
colorAttachmentDescriptor.clearColor = MTLClearColorMake(1.0f, 1.0f, 1.0f, 1.0f);
}
我省略了createDepthBufferTexture
,因为它似乎无关紧要。
最后,呈现循环不断调用renderFrame
方法:
- (void)renderFrame
{
dispatch_semaphore_wait(_bufferAccessSemaphore, DISPATCH_TIME_FOREVER);
id<CAMetalDrawable> drawable = [self.layer nextDrawable];
id<MTLTexture> framebufferTexture = drawable.texture;
self.renderPassDescriptor.colorAttachments[0].resolveTexture = framebufferTexture;
id<MTLCommandBuffer> commandBuffer = [_commandQueue commandBuffer];
// rest of the rendering code
}
我尝试将renderPassDescriptor
属性转换为实例变量,如下所示:
@implementation Renderer
{
MTLRenderPassDescriptor* _renderPassDescriptor;
// other instance variables
}
同时,我要删除表达式@property(nonatomic, strong) MTLRenderPassDescriptor* renderPassDescriptor;
。因此该属性不再存在。
此后,我仅用self.renderPassDescriptor
替换了_renderPassDescriptor
的所有调用。这样做之后,代码可以正常编译,但是在renderFrame
方法的以下行中将其炸毁:
_renderPassDescriptor.colorAttachments[0].resolveTexture = framebufferTexture;
显然,colorAttachments [0]不是nil,但是调用resolveTexture
会使应用程序崩溃。
不幸的是,由于Xcode不允许我将应用程序部署到物理iPhone(如here所述),我无法调试了。不支持在模拟器中运行Metal应用(感谢Apple!)。因此,请原谅我未指定该行到底发生了什么。
有人知道我使用属性还是实例变量为什么会有所作为?
我知道这可能是一个愚蠢的问题,可能已经存在类似的问题,但是我对Objective-C还是比较陌生,只是我自己还没有想通。
我的Xcode调试问题已解决,这意味着我可以仔细看看发生了什么。
表达式
_renderPassDescriptor.colorAttachments[0]
结果为EXC_BAD_ACCESS。因此,MTLRenderPassDescriptor*
变量_renderPassDescriptor
的行为肯定不同于相同类型的私有属性。我只是不知道为什么会这样。