开发者

NSDictionary and CTypedPtrMap-Objective C

开发者 https://www.devze.com 2023-03-05 03:28 出处:网络
c++ - CTypedPtrMap<CMapWordToPtr,WORD,stTimer*> m_cAppMap; stTimer* is a structure containing 5 values and WORD is unsigned short which is the key.

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消