NSDictionary and CTypedPtrMap-Objective C
c++ - CTypedPtrMap<CMapWordToPtr,WORD,stTimer*> m_cAppMap;
stTimer* is a structure containing 5 values and WORD is unsigned short which is the key. Is it possible to store an structure object in NSDictionary.
stTimer* pEvent; NSDictionary *dictionary = [[NSDictionary alloc]init]; [dictionary setObject:pEvent forKey:wTimerId];
Warnings:
Passing argument 1 of setobject:forKey from an incompatible pointer type
EDITED
CFMutableDictionaryRef dict = CFDictionaryCreateMutable(NULL,0,&kCFTypeDictionaryKeyCallBacks,&kCFTypeDictionaryValueCallBacks);
NSLog(@"Dict Size:%d\n",(int)((CFIndex)CFDictionaryGetCount(dict)));
CFDictionarySetValue(dict,wTimerId,pEvent);
The key and value passed should be objects in this case. But the key(wTimerId) is an unsigned short 开发者_StackOverflowint and not a pointer or an object.
How to pass it as a key?
EDITED:
Timers.h
--------
#import <Foundation/Foundation.h>
struct session {
int a;
char c;
int b;
};
@interface Timers : NSObject {
unsigned short wTimerId;
}
-(id)init;
-(void)dealloc;
-(void)timer;
@end
Timers.m
--------
#import "Timers.h"
@implementation Timers
-(id)init
{
wTimerId=91;
return self;
}
-(void)dealloc
{
[super dealloc];
}
-(void)timer
{
struct session* pEvent;
pEvent->a=10;
pEvent->c='A';
pEvent->b=20;
CFDictionaryValueCallBacks cbs = {0,NULL,NULL,NULL,NULL};
CFMutableDictionaryRef cfdict = CFDictionaryCreateMutable(NULL,0,&kCFTypeDictionaryKeyCallBacks,&cbs);
NSMutableDictionary* dict = (NSMutableDictionary*)cfdict;
//Now both the coca approach
[dict setObject:(id)pEvent forKey:[NSNumber numberWithInt:wTimerId]];
//..and the CoreFoundation aproach work
CFNumberRef timerId = CFNumberCreate(NULL,kCFNumberShortType,wTimerId);
CFDictionarySetValue(cfdict,timerId,pEvent);
NSLog(@"Dict size:%d\n",(int)((CFIndex)CFDictionaryGetCount(dict)));
CFRelease(timerId);
main.m
------
#import <Foundation/Foundation.h>
#import "Timers.h"
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
Timers* time = [[Timers alloc]init];
[time timer];
[pool drain];
return 0;
}
Its giving me EXC_BAD_ACCESS Error.
EDITED:
1.CFNumberRef timerId = CFNumberCreate(NULL,kCFNumberShortType,wTimerId);
2.NSLog(@"Dict size:%d\n",(int)((CFIndex)CFDictionaryGetCount(dict)));
warning of 1./timer/Timers.m:50:0 /timer/Timers.m:50: warning:passing argument 3 of 'CFNumberCreate' makes pointer from integer without a cast
warning of 2./timer/Timers.m:52:0 /timer/Timers.m:52: warning: passing argument 1 of 'CFDictionaryGetCount' from incompatible pointer type
I did as told in the warning by typecasting it into (unsigned short*) as the datatype of
wTimerId is unsigned short.It will give me another warning as cast to pointer from integer of different size.
You can't just pass pointers to plain structs or instances of C++ classes - NSDictionary
expects Objective-C objects confirming to the Cocoa standards.
You could store NSValue
instances in the dictionary using +valueWithPointer:
.
Alternatively you could create a CFDictionary
directly and setup the callbacks accordingly - CFDictionary
is toll-free bridged to NSDictionary
, so you can use it just like before for the most part.
Edit:
For the key the same problem applies, you can just use NSNumber
to wrap them. Also you can't use the default dictionary callbacks for the values, instead use something like:
CFDictionaryValueCallBacks cbs = {0, NULL, NULL, NULL, NULL};
CFMutableDictionaryRef cfdict =
CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &cbs);
NSMutableDictionary *dict = (NSMutableDictionary *)cfdict;
// now both the Cocoa approach:
[dict setObject:(id)pEvent forKey:[NSNumber numberWithInt:wTimerId]];
// .. and the CoreFoundation approach work:
CFNumberRef timerId = CFNumberCreate(..., &wTimerId);
CFDictionarySetValue(cfdict, timerId, pEvent);
CFRelease(timerId);
If you don't want to wrap the key you have to adjust the key callbacks as well.
精彩评论