views:

60

answers:

1

I am given some data in a callback function to write to disk sequentially, about 4KB every 0.02 seconds. If I fwrite() from the thread the callback function is in, I get some lag in other parts of code in same thread. So in order to not block this thread while writing to disk, I want to move the fwrite code to another thread. The problem is that the callback function has no instance scope, so I'm limited to calling static functions or class methods. The data I want to write belongs to the instance.

What choices do I have? I've tried NSOperationQueue with Blocks:

void (^ioBlock)(void) = ^{
        fwrite(saveBuffer, length * 4, 1, file);
    };
FileSaveOperation *op = [[FileSaveOperation alloc] initWithBlock:ioBlock];
    [opQueue addOperation:op];
    [op release];

In FileSaveOperation I set up the pool:

- (void)main
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    [NSRunLoop currentRunLoop];
    block();

    [pool release];


}

But this gives me this error:

_NSAutoreleaseNoPool(): Object 0x33ad20 of class __NSFastEnumerationEnumerator autoreleased with no pool in place - just leaking

I can't use performSelector:onThread: because I can't access the instance. Should I make my data member static? Is there a better solution?

+2  A: 

If you're not worried about supporting earlier than iOS 4.0, look at Grand Central Dispatch. You can make a block, or function pointer, inline with context captured in it. Then, you create a new queue with GCD, and it will handle all the threading for you. Just make your block call whatever you want once you're done.

All blocks remember context from where they are created. The best examples of using GCD can be found in the core OS section of the WWDC videos.

This is the method I use to complete almost all threading work these days.

DexterW