NSDictionary и CTypedPtrMap-Objective C - PullRequest
0 голосов
/ 12 мая 2011

с ++ - CTypedPtrMap<CMapWordToPtr,WORD,stTimer*> m_cAppMap;

stTimer * - это структура, содержащая 5 значений, а WORD - это беззнаковое сокращение, являющееся ключом. Можно ли сохранить объект структуры в NSDictionary.

stTimer * pEvent; NSDictionary * dictionary = [[NSDictionary alloc] init]; [словарь setObject: pEvent forKey: wTimerId];

Предупреждения:

Передача аргумента 1 объекта-объекта: forKey из несовместимого типа указателя

EDITED

CFMutableDictionaryRef dict = CFDictionaryCreateMutable(NULL,0,&kCFTypeDictionaryKeyCallBacks,&kCFTypeDictionaryValueCallBacks);
    NSLog(@"Dict Size:%d\n",(int)((CFIndex)CFDictionaryGetCount(dict)));
    CFDictionarySetValue(dict,wTimerId,pEvent);

В этом случае передаваемый ключ и значение должны быть объектами. Но ключ (wTimerId) - это короткое целое без знака, а не указатель или объект.

Как передать его как ключ?

РЕДАКТИРОВАНИЕ:

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;
}

Это дает мне EXC_BAD_ACCESS Ошибка.

РЕДАКТИРОВАНИЕ:

1.CFNumberRef timerId = CFNumberCreate(NULL,kCFNumberShortType,wTimerId);

2.NSLog(@"Dict size:%d\n",(int)((CFIndex)CFDictionaryGetCount(dict)));

предупреждение от 1./timer/Timers.m:50:0 /timer/Timers.m:50: warning: передача аргумента 3 'CFNumberCreate' делает указатель из целого числа без приведения

предупреждение от 2./timer/Timers.m:52:0 /timer/Timers.m:52: предупреждение: передача аргумента 1 'CFDictionaryGetCount' из несовместимого типа указателя

Я сделал, как сказано в предупреждении, введя его в (unsigned short *) как тип данных

wTimerId является коротким без знака. Это даст мне еще одно предупреждение, когда приведен к указателю из целого числа другого размера .

1 Ответ

3 голосов
/ 12 мая 2011

Нельзя просто передавать указатели на простые структуры или экземпляры классов C ++ - NSDictionary ожидает объекты Objective-C, соответствующие стандартам Какао.

Вы можете хранить NSValue экземпляры в словаре, используя+valueWithPointer:.
В качестве альтернативы вы можете создать CFDictionary напрямую и настроить обратные вызовы соответствующим образом - CFDictionary бесплатен для моста NSDictionary, так что вы можетеиспользуйте его, как и прежде, по большей части.

Редактировать:
Для ключа применима та же проблема, вы можете просто использовать NSNumber, чтобы обернуть их.Также вы не можете использовать обратные вызовы словаря по умолчанию для значений, вместо этого используйте что-то вроде:

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);

Если вы не хотите оборачивать ключ, вам также необходимо настроить обратные вызовы ключа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...