Re: Help with NSPointerArray and NSMapTable

Jonathan Dann <[email protected]>
Newsgroups gmane.comp.macosx.devel
Message-ID <[email protected]>
Looks like I can't post from my work email...

On 21 Sep 2009, at 20:22, Christiaan Hofman wrote:

> I am trying to create arrays and dictionaries containing non-object  
> types like NSInteger, CGFloat, and structs like NSRect. This should  
> be possible using NSPointerArray/NSMapTable and appropriate pointer  
> functions. But I am very much confused about which pointer function  
> options to use and how to add/remove values.
[snip]

Hi Christiaan,

You're along the right lines but you need to also set the sizeFunction  
on the NSPointerFunctions. This is a pointer to a function that  
returns the size of type you'll be using in the array. The collections  
(presumably) use the size function in the malloc() call when they take  
ownership of the value. I have some categories on NSPointerFunctions  
and NSPointerArray for the common struct types:

@implementation NSPointerFunctions (ESAdditions)

static NSUInteger _ESPointerArrayCGRectStructSize(const void *item)
{
	return sizeof(CGRect);
}

static NSUInteger _ESPointerArrayCGPointStructSize(const void *item)
{
	return sizeof(CGPoint);
}

static NSUInteger _ESPointerArrayNSRangeStructSize(const void *item)
{
	return sizeof(NSRange);
}

static NSUInteger _ESPointerArrayCGSizeStructSize(const void *item)
{
	return sizeof(CGSize);
}


+ (NSPointerFunctions *)pointerFunctionsForNSRange;
{
	NSPointerFunctions *aPointerFunctions = [NSPointerFunctions  
pointerFunctionsWithOptions:(NSPointerFunctionsStructPersonality| 
NSPointerFunctionsMallocMemory|NSPointerFunctionsCopyIn)];
	[aPointerFunctions setSizeFunction:&_ESPointerArrayNSRangeStructSize];
	return aPointerFunctions;
}

+ (NSPointerFunctions *)pointerFunctionsForCGRect;
{
	NSPointerFunctions *aPointerFunctions = [NSPointerFunctions  
pointerFunctionsWithOptions:(NSPointerFunctionsStructPersonality| 
NSPointerFunctionsMallocMemory|NSPointerFunctionsCopyIn)];
	[aPointerFunctions setSizeFunction:&_ESPointerArrayCGRectStructSize];
	return aPointerFunctions;
}

+ (NSPointerFunctions *)pointerFunctionsForCGPoint;
{
	NSPointerFunctions *aPointerFunctions = [NSPointerFunctions  
pointerFunctionsWithOptions:(NSPointerFunctionsStructPersonality| 
NSPointerFunctionsMallocMemory|NSPointerFunctionsCopyIn)];
	[aPointerFunctions setSizeFunction:&_ESPointerArrayCGPointStructSize];
	return aPointerFunctions;
}

+ (NSPointerFunctions *)pointerFunctionsForCGSize;
{
	NSPointerFunctions *aPointerFunctions = [NSPointerFunctions  
pointerFunctionsWithOptions:(NSPointerFunctionsStructPersonality| 
NSPointerFunctionsMallocMemory|NSPointerFunctionsCopyIn)];
	[aPointerFunctions setSizeFunction:&_ESPointerArrayCGSizeStructSize];
	return aPointerFunctions;
}
@end

@implementation NSPointerArray (ESExtensions)

+ (id)rangePointerArray;
{
	return [[[self alloc] initWithPointerFunctions:[NSPointerFunctions  
pointerFunctionsForNSRange]] autorelease];
}
			
+ (id)rectPointerArray;
{
	return [[[self alloc] initWithPointerFunctions:[NSPointerFunctions  
pointerFunctionsForCGRect]] autorelease];
}

+ (id)pointPointerArray;
{
	return [[[self alloc] initWithPointerFunctions:[NSPointerFunctions  
pointerFunctionsForCGPoint]] autorelease];
}

+ (id)sizePointerArray;
{
	return [[[self alloc] initWithPointerFunctions:[NSPointerFunctions  
pointerFunctionsForCGSize]] autorelease];
}

@end

If you add NS_BUILD_32_LIKE_64 to the preprocessor macros in Xcode,  
you can use CG/NS Rect, Point and Size interchangeably.

Note that +[NSPointerArray pointerArrayWithPointerFunctions:] seems to  
crash on 10.5.x, hence the -initWith... calls.

In you client code, do something like

NSRect aRect = NSZeroRect;
NSPointerArray *aRectArray = [NSPointerArray rectPointerArray];
[aRectArray addPointer:&aRect];

// some time later ......

NSRect aRect = *(NSRectPointer)[aRectArray pointerAtIndex:index]

Hope this helps,

Jonathan
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.