【问题标题】:String as key in a mapping字符串作为映射中的键
【发布时间】:2011-06-08 04:17:40
【问题描述】:

我想用字符串键在NSMutableDictionary 中存储一个对象,所以我做了这样的声明:

[m_pMsgIdToStructMap setObject:pStruct 
                        forKey:[NSMutableString stringWithString:pStruct->szAsciiName]];

szAsciiName 在 .h 文件中声明为 NSMutableString *。 我没有收到任何警告或错误,但我想确认我所做的声明是否正确。

已编辑:

嗨,

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 异常。

【问题讨论】:

  • 您是否尝试回读对象以确认它是正确的?
  • 那么您在取出对象时遇到问题吗?您是否遇到数据损坏或其他问题?我不确定你的问题是什么。如果只是“这行得通吗?”那么答案是“你试过了吗?”
  • 在 NSDictionary 中使用 NSMutableString 作为键是个坏主意。请记住,字典会散列其键。当你把它们放进去时,它会这样做。如果你改变字符串,它的哈希值会不同,但字典无法知道这一点,所以如果你尝试查找 相同的字符串 (字典会要求它的哈希值,它会改变,所以字典将通过它的新哈希值查找字符串),它不会找到它。仅使用不可变字符串。如果要更改密钥,请删除旧密钥的对象并添加/更改新密钥的对象。
  • Peter Hosey 有一次错了:使用 NSMutableString 作为字典键是安全的,但它可能无法达到你想要的效果。 NSDictionary 键被复制,因此实际的键将是字符串的不可变副本,就像它被添加到字典时一样。
  • @Ahruman 我总是忘记 NSDictionary 复制它的键,但这并没有改变重点:尝试查找您变异的字符串将失败,因为字典复制(并散列)旧的版本。您可以使用不打算保留的可变字符串,因为字典会复制它,但如果您要保留可变字符串(稍后对其进行变异),您将无法找到相同的字符串变异后字典中的字符串。

标签: objective-c cocoa nsmutablestring


【解决方案1】:

猜测,pStruct 不是 NSObject,它是一个原始结构(假设您使用 -> 取消引用 szAsciiName)。

如果不进行更多调整,这将无法正常工作。您可以通过安装客户发布/保留处理程序使 CFDictionary 保留到非 NSObject。

【讨论】:

  • 谢谢。使用 CFDictionary 对我来说是新的。我会尝试这样做。
  • @spandana:指向非对象的指针在 CFDictionary 中完全有效,只要您为其提供正确的回调集。您正在使用 NSDictionary,它没有自定义选项(没有回调),因此您只能使用 Cocoa/CF 对象。
  • @Peter Hosey:是的。使用 CFDictionary 是个好主意。但我没有这样做的先验知识。我会尝试这样做。但是有没有可能添加一个字符串作为字典的键。
  • @spandana:我不建议使用 CFDictionary。我认为没有理由不使用 NSDictionary。无论如何,您都应该将结构替换为模型对象类,这样做将使您能够使用 NSDictionary。
  • @Peter Hosey:是的,会用那个 NSData 做到这一点。
猜你喜欢
  • 2021-08-30
  • 2020-01-15
  • 1970-01-01
  • 2015-03-16
  • 1970-01-01
  • 2018-04-27
  • 1970-01-01
  • 1970-01-01
  • 2012-08-27
相关资源
最近更新 更多