discuss-gnustep
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Wrapping C functions


From: David Chisnall
Subject: Re: Wrapping C functions
Date: Thu, 6 Aug 2009 22:38:05 +0100

On 6 Aug 2009, at 22:13, Martin Kalbfuß wrote:


OK. I understand that a global and load isn't needed when using a singleton.
The atexit cleanup is mainly for calling SDL_Quit;
I followed an example of apple for a singleton. Now my implementation looks
like:

static Oh *sharedOhMangager = nil;

@implementation Oh

        +(  Oh * )sharedMangager
        {
                @synchronized(self)
                {
                        if ( sharedOhInstance == nil )
                        {
                                [ [ self alloc ] init ];
                        }
                }

                return sharedOhManager;
        }

This is ugly. @synchronized is very slow and not required if you use +initialize to create the singleton.

        + ( id )allocWithZone:( NSZone * )zone
        {
                @synchronized( self )
                {
                if ( sharedOhManager == nil )
                        {
                                SDL_Init();

                                sharedOhManager = [ super allocWithZone: zone ];

                                return sharedOhManager;
                }
                }

                return nil;
        }

Put the SDL_Init() code in +initialize. If you create the singleton in +initialize then you don't need the synchronization code here either. Anything in +initialize is guaranteed to only be called by one thread; the runtime handles synchronization. Replace these two with:

+ (Oh*)sharedMangager
{
        return sharedOhManager;
}

+ (id)allocWithZone:( NSZone * )zone
{
        if (nil ==  sharedOhManager)
        {
                return [super allocWithZone: zone];
        }
        return nil;
}

+ (void)initialize
{
        if ([Oh class] != self) { return; }
        SDL_Init();
        sharedOhManager = [self new];
}

This is less code, simpler, and will be faster. The implementation of @synchronized() in GNUstep is horrible (there's a slightly better one in Étoilé's ObjectiveC2 framework) and means that every time you use an @synchronized() directive in code that is reached, it makes all other @synchronized() directive's slightly cheaper.

        - ( id )copyWithZone:( NSZone * )zone
        {
                return self;
        }

        - ( unsigned ) retainCount
        {
                return UINT_MAX;
        }

        - ( void )release
        {
        }

        - ( id )autorelease
        {
                return self;
        }

This all looks sensible.


@end

But what I don't understand is where the objects memory is going to be
freed. They don't tell. They only say it's for memory-managed code. Release and autorelease are overwritten. Should I or the user call dealloc somwhere?

Singletons aren't freed, they persist for the lifespan of the program.

The documentation for SDL_Quit() implies that it actually needs to be called, which is a bit strange; the OS should be able to reclaim any resources when the program exits. The best way of doing this is by registering for aNSApplicationWillTerminateNotification notification from NSApp. If NSApp doesn't exist, then you need to make sure that your application calls a method in the object that calls SDL_quit().

David



reply via email to

[Prev in Thread] Current Thread [Next in Thread]