Sheets, blocks and garbage collector
-
Hi all,
I'm beginning a new application targeting Snow Leopard only. So I want to use the new tools (blocks) and garbage collection (GC). It will be my first application using GC.
I read some sites on GC and blocks. In the blog of Mike Ash I found some very interesting propositions. My question concerns his code for using block with sheets (http://www.mikeash.com/?page=pyblog/friday-qa-2009-08-14-practical-blocks.h
tml). Is this code works in GC ?
@implementation NSApplication (SheetAdditions)
- (void)beginSheet: (NSWindow *)sheet modalForWindow:(NSWindow *)docWindow didEndBlock: (void (^)(NSInteger returnCode))block
{
[self beginSheet: sheet
modalForWindow: docWindow
modalDelegate: self
didEndSelector: @selector(my_blockSheetDidEnd:returnCode:contextInfo:)
contextInfo: [block copy]];
}
- (void)my_blockSheetDidEnd: (NSWindow *)sheet returnCode: (NSInteger)returnCode contextInfo: (void *)contextInfo
{
void (^block)(NSInteger returnCode) = contextInfo;
block(returnCode);
[block release];
}
@end
I think, I have to replace [block copy] by CFRetain([block copy])
and [block release] by CFRelease(block).
Frédéric -
2010/2/6 Frédéric Testuz <ftestuz...>:
> Hi all,
>
> I'm beginning a new application targeting Snow Leopard only. So I want to use the new tools (blocks) and garbage collection (GC). It will be my first application using GC.
>
> I read some sites on GC and blocks. In the blog of Mike Ash I found some very interesting propositions. My question concerns his code for using block with sheets (http://www.mikeash.com/?page=pyblog/friday-qa-2009-08-14-practical-blocks.h
tml). Is this code works in GC ?
>
> @implementation NSApplication (SheetAdditions)
>
> - (void)beginSheet: (NSWindow *)sheet modalForWindow:(NSWindow *)docWindow didEndBlock: (void (^)(NSInteger returnCode))block
> {
>
> [self beginSheet: sheet
> modalForWindow: docWindow
> modalDelegate: self
> didEndSelector: @selector(my_blockSheetDidEnd:returnCode:contextInfo:)
> contextInfo: [block copy]];
> }
>
> - (void)my_blockSheetDidEnd: (NSWindow *)sheet returnCode: (NSInteger)returnCode contextInfo: (void *)contextInfo
> {
> void (^block)(NSInteger returnCode) = contextInfo;
> block(returnCode);
> [block release];
> }
>
> @end
>
> I think, I have to replace [block copy] by CFRetain([block copy])
> and [block release] by CFRelease(block).
I believe your GC modifications are correct. As you've presumably
determined already, [block copy] alone isn't enough to keep the block
alive through the void *.
If you happen to be writing dual-mode code, you can write code that
works in both GC and refcounted environments by writing
CFRetain([block copy]) in the first part and CFRelease(block); [block
release]; in the second.
Mike -
Le 6 févr. 2010 à 17:55, Michael Ash a écrit :
> 2010/2/6 Frédéric Testuz <ftestuz...>:
>> Hi all,
>>
>> I'm beginning a new application targeting Snow Leopard only. So I want to use the new tools (blocks) and garbage collection (GC). It will be my first application using GC.
>>
>> I read some sites on GC and blocks. In the blog of Mike Ash I found some very interesting propositions. My question concerns his code for using block with sheets (http://www.mikeash.com/?page=pyblog/friday-qa-2009-08-14-practical-blocks.h
tml). Is this code works in GC ?
>>
>> @implementation NSApplication (SheetAdditions)
>>
>> - (void)beginSheet: (NSWindow *)sheet modalForWindow:(NSWindow *)docWindow didEndBlock: (void (^)(NSInteger returnCode))block
>> {
>>
>> [self beginSheet: sheet
>> modalForWindow: docWindow
>> modalDelegate: self
>> didEndSelector: @selector(my_blockSheetDidEnd:returnCode:contextInfo:)
>> contextInfo: [block copy]];
>> }
>>
>> - (void)my_blockSheetDidEnd: (NSWindow *)sheet returnCode: (NSInteger)returnCode contextInfo: (void *)contextInfo
>> {
>> void (^block)(NSInteger returnCode) = contextInfo;
>> block(returnCode);
>> [block release];
>> }
>>
>> @end
>>
>> I think, I have to replace [block copy] by CFRetain([block copy])
>> and [block release] by CFRelease(block).
>
> I believe your GC modifications are correct. As you've presumably
> determined already, [block copy] alone isn't enough to keep the block
> alive through the void *.
>
> If you happen to be writing dual-mode code, you can write code that
> works in both GC and refcounted environments by writing
> CFRetain([block copy]) in the first part and CFRelease(block); [block
> release]; in the second.
Thanks for your answer and for the completion. It will make the code reusable for another case without GC.
Frédéric


