Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7987779
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 4, 20262026-06-04T12:14:49+00:00 2026-06-04T12:14:49+00:00

Situation: I need to pass an Objective-C object to an asynchronous C API as

  • 0

Situation:

I need to pass an Objective-C object to an asynchronous C API as an opaque reference (void*) which will later be passed to the callback function I provide. The callback then calls a method on the object. The code needs to work in the presence of garbage collection, and the object must not be GC’d between my call to the C API and the time my callback is called by it.

The NSGarbageCollector class provides the disableCollectorForPointer: and enableCollectorForPointer: methods for marking and unmarking objects as uncollectable roots.

Question:

What I can’t work out from the docs and searching the web is if the calls to disableCollectorForPointer: are counted and must be balanced by the same number of enableCollectorForPointer: calls. If this is not the case and each object is either flagged as root or not, calling enableCollectorForPointer: in my callback might clear an existing root flag set by some other code, causing the object to be collected even though it shouldn’t!

The alternative I’ve seen is to use CFRetain and CFRelease – are these safe to use on my own NSObject subclasses? I’ve only used these functions on toll-free-bridged CF objects before.

Bonus points for answers which provide evidence. I see disableCollectorForPointer: recommended all over the place, with no mention of this safety aspect.

Notes:

  • I have to support garbage collection as this code will be used by a PrefPane for System Preferences. The 64-bit version of a PrefPane must use garbage collection. So using ARC or manual refcounting is not an option.
  • The C API is one of Apple’s (IOKit) so I have no control over it either.
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-04T12:14:51+00:00Added an answer on June 4, 2026 at 12:14 pm

    I think I’ve found the answer. Source code for the garbage collector doesn’t seem to be available, but the header file declaring the interface for NSGarbageCollector, NSGarbageCollector.h from the Foundation.framework contains the following:

    // references outside the heap, globals, and the stack, e.g. unscanned memory, malloc memory, must be tracked by the collector
    - (void)disableCollectorForPointer:(void *)ptr;     // this pointer will not be collected...
    - (void)enableCollectorForPointer:(void *)ptr;      // ...until this (stacking) call is made
    

    Note the “stacking” comment – I assume this means that calls are indeed counted? More evidence still welcome!

    Update:

    Just to be really sure, I decided to test my hypothesis using a little test program (gcbridgetest.m):

    #import <Foundation/Foundation.h>
    
    @interface PJGarbageCollectionTest : NSObject
    @end
    
    @implementation PJGarbageCollectionTest
    
    - (id)init
    {
        self = [super init];
        if (!self) return nil;
        NSLog(@"%@ -init", self);
        return self;
    }
    
    - (void)finalize
    {
        NSLog(@"%@ -finalize", self);
        [super finalize];
    }
    
    @end
    
    static void* ext_ptr1 = NULL;
    static void* ext_ptr2 = NULL;
    
    static void create()
    {
        PJGarbageCollectionTest* test = [[PJGarbageCollectionTest alloc] init];
        [[NSGarbageCollector defaultCollector] disableCollectorForPointer:test];
        ext_ptr1 = test;
        [[NSGarbageCollector defaultCollector] disableCollectorForPointer:test];
        ext_ptr2 = test;
    }
    
    static void killref(void** ext_ptr)
    {
        [[NSGarbageCollector defaultCollector] enableCollectorForPointer:*ext_ptr];
        *ext_ptr = NULL;
    }
    
    
    int main()
    {
        NSLog(@"collector: %@", [NSGarbageCollector defaultCollector]);
        create();
        NSLog(@"Collecting with 2 external references");
        [[NSGarbageCollector defaultCollector] collectExhaustively];
        killref(&ext_ptr1);
        NSLog(@"Collecting with 1 external reference");
        [[NSGarbageCollector defaultCollector] collectExhaustively];
        killref(&ext_ptr2);
        NSLog(@"Collecting with 0 external references");
        [[NSGarbageCollector defaultCollector] collectExhaustively];
        return 0;
    }
    

    Compiled with gcc -fobjc-gc-only -g -Wall -Wextra -ObjC gcbridgetest.m -framework Foundation -o gcbridgetest and run as ./gcbridgetest, it gives the following output, confirming that enable/disableCollectorForPointer: calls are indeed counted:

    2012-06-12 16:08:08.278 gcbridgetest[29712:903] collector: <NSGarbageCollector: 0x20000f420>
    2012-06-12 16:08:08.281 gcbridgetest[29712:903] <PJGarbageCollectionTest: 0x20000ee60> -init
    2012-06-12 16:08:08.284 gcbridgetest[29712:903] Collecting with 2 external references
    2012-06-12 16:08:08.285 gcbridgetest[29712:903] Collecting with 1 external reference
    2012-06-12 16:08:08.286 gcbridgetest[29712:903] Collecting with 0 external references
    2012-06-12 16:08:08.286 gcbridgetest[29712:903] <PJGarbageCollectionTest: 0x20000ee60> -finalize
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have two activities in which I need to pass an object array between
Hey i have a situation in which i need to pass some variable value
I have a situation as below in which I need to pass a C-style
So I've got a situation where I need to pass a bunch of data
Situation: I need to make an imap client (using java mail api) that if,
I have the following situation: I have a object of type MyClass , which
i have a situation here where i need to pass the date as sysdate
I have a situation where I need to pass the name of the child
So, I have a situation where I need to pass in three values into
I have some data which I need to pass on to a recursive function.

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.