#objective-c #cocoa #nsmutablestring
#objective-c #cocoa #nsmutablestring
Вопрос:
Я хочу сохранить объект в NSMutableDictionary
со строковым ключом, поэтому я сделал объявление следующим образом:
[m_pMsgIdToStructMap setObject:pStruct
forKey:[NSMutableString stringWithString:pStruct->szAsciiName]];
szAsciiName
объявлена как NSMutableString *
в файле .h.
Я не получаю никаких предупреждений или ошибок, но я хочу подтвердить, является ли объявление, которое я делаю, правильным.
ОТРЕДАКТИРОВАНО:
Привет,
main.m
-------
#import <Foundation/Foundation.h>
#import "string.h"
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
stringss* stringsss = [[stringss alloc]init];
//NSMutableString* strs = [[NSMutableString alloc]initWithFormat:"First"];
[stringsss trail:@"First"]; //getting warning:Passing argument 1 of 'trail' from incompatible pointer type
[pool drain];
return 0;
}
stringss.h
----------
#import <Foundation/Foundation.h>
typedef struct
{
int a;
int b;
NSMutableString* szAsciiName;
}st;
@interface stringss : NSObject {
NSMutableDictionary* m_map;
}
-(void)trail:(const char*)szAsciiName;
@end
stringss.m
---------
#import "string.h"
@implementation stringss
-(id)init
{
if (self = [super init]) {
m_map = [[NSMutableDictionary alloc]init];
//pStruct->szAsciiName = [[NSMutableString alloc]init];
}
return self;
}
-(void)trail:(NSString*)szAsciiName
{
st* pStruct = malloc(sizeof(st));
st* pStruct1 = malloc(sizeof(st));
pStruct->a = 10;
pStruct->b = 20;
pStruct->szAsciiName = [[NSMutableString alloc]init];
pStruct->szAsciiName = (NSMutableString*)szAsciiName;
[m_map setObject:(void*)pStruct forKey:szAsciiName];
pStruct1 = (st*)[[m_map objectForKey:szAsciiName]bytes];
}
@end
Я также получаю исключение EXC_BAD_ACCESS.
Комментарии:
1. Вы пытались прочитать объект обратно, чтобы подтвердить его правильность?
2. Итак, у вас возникли проблемы с извлечением объекта обратно? У вас возникли проблемы с повреждением данных или что-то в этом роде? Я не уверен, в чем заключается ваш вопрос. Если это просто «Работает ли это?», то ответ будет «Вы пробовали это?»
3. Использование NSMutableString в качестве ключа в NSDictionary — плохая идея. Помните, что словарь хэширует свои ключи. Это происходит, когда вы их вводите. Если вы измените строку, ее хэш будет другим, но у словаря нет способа узнать это, поэтому, если вы затем попытаетесь найти ту же строку (словарь запросит ее хэш, который будет изменен, поэтому словарь будет искать строку по ее новому хэшу), он ее не найдет. Используйте только неизменяемые строки. Если вы хотите изменить ключ, удалите объект для старого ключа и добавьте / измените объект для нового.
4. Питер Хоси на этот раз ошибается: использование NSMutableString в качестве ключа словаря безопасно, но оно может не выполнять то, что вы хотите. Ключи NSDictionary копируются, поэтому фактический ключ будет неизменяемой копией вашей строки, какой она была при добавлении в словарь.
5. @Ahruman Я всегда забываю, что NSDictionary копирует свои ключи, но это не меняет сути: попытка найти строку, которую вы изменили, завершится неудачей, потому что словарь скопировал (и хэшировал) старую версию. Вы можете использовать изменяемую строку, которую вы не собираетесь сохранять, поскольку словарь скопирует ее, но если вы собираетесь сохранить изменяемую строку (чтобы изменить ее позже), вы не сможете найти ту же строку в словаре после ее изменения.
Ответ №1:
На мой взгляд, pStruct — это не NSObject, это необработанная структура (учитывая, что вы используете -> для разыменования szAsciiName).
Это не сработает без дополнительной настройки. Вы можете сохранить CFDictionary для объектов, отличных от NSObject, установив обработчики выпуска / сохранения клиента.
Комментарии:
1. Спасибо. Использование CFDictionary для меня ново. Я попытаюсь это сделать.
2. @spandana: Указатели на не-объекты абсолютно допустимы в CFDictionary, если вы предоставляете ему правильный набор обратных вызовов. Вы используете NSDictionary, у которого нет опции настройки (нет обратных вызовов), поэтому вы можете использовать с ним только объекты Cocoa / CF.
3. @Питер Хоси: Да. Использовать CFDictionary — хорошая идея. Но у меня нет предварительных знаний для этого. Я попытаюсь это сделать. Но есть ли какая-либо возможность добавления строки в качестве ключа в словарь.
4. @spandana: Я не предлагал использовать CFDictionary. Я не вижу причин не использовать NSDictionary. Вам в любом случае следует заменить struct классом model object, и это позволит вам использовать NSDictionary.
5. @Peter Hosey: да, я сделаю это с этими NSData.