Я пытаюсь преобразовать существующее частное свойство в переменную экземпляра. Этот вопрос не о том, должен ли я держать это в частной собственности или нет. Я знаю о преимуществах свойств. Однако в моем случае (по крайней мере, я так думал), что они мне не нужны.
Итак, частная собственность, которую я хочу преобразовать, объявлена следующим образом:
@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] не ноль, а вызов resolveTexture
приводит к сбою приложения.
К сожалению, я больше не могу отлаживать, потому что Xcode не позволяет мне развертывать мое приложение на физических iPhone (как описано здесь ). Запуск металлического приложения в симуляторе не поддерживается (спасибо, Apple!). Поэтому, пожалуйста, прости меня за то, что я не уточнил, что именно происходит на этой линии.
Кто-нибудь знает, почему будет иметь значение, использовать ли я свойство или переменную экземпляра?
Я знаю, что это может быть глупый вопрос, и схожие вопросы уже могут быть, но я относительно новичок в Objective-C и просто сам еще не понял этого.
EDIT:
Моя проблема отладки Xcode решена, что означает, что я мог бы более внимательно посмотреть на то, что происходит.
Выражение
_renderPassDescriptor.colorAttachments[0]
приводит к EXC_BAD_ACCESS. Таким образом, переменная MTLRenderPassDescriptor*
_renderPassDescriptor
определенно ведет себя иначе, чем личное свойство того же типа. Мне просто не хватает понимания, почему это так.