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
previous month february 2010 next month
MTWTFSS
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
Go to today