Created
May 15, 2016 07:00
-
-
Save swillits/36919b9c06b941cb6e992959f37b67ff to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ================================================================ | |
// Example 1: | |
@implementation MTLRenderPassDescriptor | |
+ (MTLRenderPassDescriptor *)renderPassDescriptor | |
{ | |
// We know this method returns an "autoreleased" object because it's not alloc or copy. | |
// This is basically what it could look like... | |
return [[[MTLRenderPassDescriptor alloc] init] autorelease]; | |
} | |
@end | |
// Somewhere in your code ... | |
@implementation FooInYourCode | |
- (void)blah | |
{ | |
// No need to call release. It's already in balance because | |
// renderPassDescriptor returns an autoreleased instance | |
MTLRenderPassDescriptor * renderPassDesc = [MTLRenderPassDescriptor renderPassDescriptor]; | |
} | |
@end | |
// This demonstrates some code higher up in the stack which is creating | |
// the autorelease pool. Usuall this would be the NSRunLoop on the main thread, for example. | |
@implementation Something_UsuallyTheMainThreadNSRunLoop | |
- (void)tick | |
{ | |
// Create a pool, which sets it as the current autorelease pool on the thread... | |
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; | |
{ | |
// Someway somehow your method gets called... | |
[foo blah]; | |
// -blah calls +renderPassDescriptor, which calls -autorelease on the renderPassDesc instance. | |
// -autorelease gives "the current autorelease pool" (eg 'pool' above) a reference to the receiving | |
// object, eg 'renderPassDesc'. So 'renderPassDesc' is now in the pool. | |
} | |
// 'pool' itself will be deallocated here since its retain count drops to zero, | |
// so pool calls -release on 'renderPassDesc' balancing the +alloc inside +renderPassDescriptor, | |
// which then makes renderPassDesc's retain count fall to 0 and be deallocated. No leak. | |
[pool release]; | |
} | |
@end | |
// ================================================================ | |
// Example 2 | |
@implementation RendererFactory // for illustration... | |
- (Renderer *)makeRenderer | |
{ | |
// Create the render pass desc... it's autoreleased | |
MTLRenderPassDescriptor * renderPassDesc = [MTLRenderPassDescriptor renderPassDescriptor]; | |
// Pass it to this renderer. If the renderer is going to keep the RPD around, | |
// then the renderer itself is responsible for retaining it. | |
Renderer * renderer = [[Renderer alloc] initWithPassDesc:renderPassDesc other:otherObject]; | |
// RendererFactory isn't going to keep a reference to the renderer, | |
// so call -autorelease, so the retain count is effectively in balance, | |
// and the caller does *not* need to explicitly release the renderer, | |
// just to balance an allocation. | |
return [renderer autorelease]; | |
} | |
@end | |
@implementation Renderer | |
{ | |
MTLRenderPassDescriptor * _renderPassDesc; | |
} | |
- (instancetype)initWithPassDesc:(MTLRenderPassDescriptor *)rpd other:(id)obj | |
{ | |
if (!(self = [super init])) { | |
return nil; | |
} | |
// Retaining because this 'Renderer' instance will use the rpd obj later, | |
// after init returns. | |
_renderPassDesc = [rpd retain]; | |
// ... | |
return self; | |
} | |
- (void)dealloc | |
{ | |
// Simply balancing the -retain in our -init. | |
// Doesn't necessarily dealloc. Other renderers could reference / "own" this same RPD instance too. | |
[_renderPassDesc release]; | |
[super dealloc]; | |
} | |
- (void)renderFrame | |
{ | |
// Reusing _renderPassDesc each frame | |
id<MTLCommandBuffer> commandBuffer = ...; | |
id<MTLRenderCommandEncoder> renderCE = [commandBuffer renderCommandEncoderWithDescriptor:_renderPassDesc]; | |
// ... | |
} | |
@end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment