Created
February 14, 2018 09:05
-
-
Save Tricertops/515eb6fda9176a16e8a577a47d86b76d to your computer and use it in GitHub Desktop.
Implementation of NSFastEnumeration on top of CFBinaryHeap. The only way to get objects from CFBinaryHeap is to use allocated object buffer, but NSFastEnumeration doesn’t provide a way to free() it explicitly. I used autoreleased NSMutableData to manage the buffer and it somehow works.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id __unsafe_unretained [])providedBuffer count:(NSUInteger)providedLength { | |
// If this is not first invocation, finish by returning 0. | |
if (state->state != 0) { | |
return 0; | |
} | |
let count = CFBinaryHeapGetCount(self->_underlayingHeap); | |
// We are empty. | |
if (count == 0) { | |
return 0; | |
} | |
// We can only get all objects at once into a pre-allocated buffer. This doesn’t work nicely with NSFastEnumeration. | |
__autoreleasing var data = [[NSMutableData alloc] initWithLength:count * sizeof(id)]; | |
CFBinaryHeapGetValues(self->_underlayingHeap, data.mutableBytes); | |
// The autoreleased NSData will live long enough to provide the underlaying buffer until for-in loop finishes. | |
state->state = count; | |
state->itemsPtr = (id __unsafe_unretained *) data.mutableBytes; | |
state->mutationsPtr = data.mutableBytes; // Required to be non-nil. | |
return count; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment