Edit: Okay, I'm stupid as hell. This is expected behavior, I was just too stupid to see it.
The problem is inside the LFRelease() function, it removes the object first from the run loop which releases the object again after it retained it, setting its retain count back to zero.
This works in all other cases because it leaves the retain count untouched, however it fails in this case for obvious reasons. Here is a working version of the LFRelease() function:
LFTypeRef *LFRelease(LFTypeRef *ref)
{
if(ref->type == LFTYPE_ZOMBIE)
{
printf("Releasing already deallocated object %p!\n", ref);
return NULL;
}
ref->retainCount -= 1;
if(ref->retainCount == 0)
{
if(ref->type == LFTYPE_RUNLOOP)
{
LFRunLoop *runLoop = (LFRunLoop *)ref->data;
if(runLoop->running) // A running runloop can't be deallocated!
{
runLoop->dirty = 1;
runLoop->shouldStop = 1;
ref->retainCount ++;
return ref;
}
}
if(ref->runLoop && LFRunLoopCurrentRunLoop())
{
ref->retainCount = 2;
LFRunLoopRemoveObject(LFRunLoopCurrentRunLoop(), ref);
ref->retainCount = 0;
}
if(ref->pool)
{
LFAutoreleasePoolRef *_pool = (LFAutoreleasePoolRef *)ref->pool;
ref->pool = NULL;
ref->retainCount = 2; // Avoid double realeasing when removing the object from the array
LFAutoreleasePool *pool = (LFAutoreleasePool *)_pool->data;
LFArrayRemoveObject(pool->objects, ref);
ref->retainCount = 0;
}
if(ref->dealloc)
ref->dealloc(ref);
if(ref->data)
free(ref->data);
if(!LFZombieFactory)
free(ref);
else
ref->type = LFTYPE_ZOMBIE;
return NULL;
}
return ref;
}
Please remark: I won't update the current version, you have to copy the patch manually as I'm almost finished with the next version (which will of course include the patch)!
Thanks superku and bunsen!
Edit: Whoops, this shouldn't be a double post. Sorry, clicked the wrong button. Can a mod please merge the two posts?