NSMutableDictionary转换为__ NSCFString

时间:2011-12-14 10:57:27

标签: ios nsmutabledictionary nscfstring

我正在开发iOS 4应用程序。

我有一个带有NSMutableDictionary属性的类:

@interface CardHelper : NSObject <NSXMLParserDelegate>{
    ...

    NSMutableDictionary* cards;

    ...
}

@property (nonatomic, readonly) NSMutableDictionary* cards;

- (id)initWithXMLFile:(NSString *)xmlFileName andLanguage:(NSString *)language;
...

我在这里创建了NSMutableDictionary:

...
#define kNumCards 22
...

- (id)initWithXMLFile:(NSString *)xmlFileName andLanguage:(NSString *)language
{
    if (self = [super init])
    {
        userLanguage = [NSString stringWithString:language];

        cards = [NSMutableDictionary dictionaryWithCapacity: kNumCards];

        [self parseXMLFile:[self GetResourcePathFor:xmlFileName OfType:@"xml"]];

        return self;
    }
    else
        return nil;
}

我在这里添加元素:

- (void) parser:(NSXMLParser *)parser
  didEndElement:(NSString *)elementName
   namespaceURI:(NSString *)namespaceURI
  qualifiedName:(NSString *)qName
{
    NSLog(@"DidEndElement: %@", elementName);
    if ([elementName isEqualToString:@"card"])
    {
        [cards setObject:currentCard forKey:currentCard.Number];
        [currentCard release];
        currentCard = nil;

        return;
    }

    ...
}

CardHelper对象是在名为ViewController的类(我的应用程序的主视图控制器)上创建的。从这个视图控制器我显示另一个:

- (IBAction)oneCardCliked:(id)sender
{
    oneViewController = [[OneCardViewController alloc] init];
    oneViewController.cardHelper = cardHelper;

    [self presentModalViewController:oneViewController animated:YES];
}

在ViewController中定义的CardHelper:

@interface ViewController : UIViewController {
    ...
    CardHelper* cardHelper;
    ...
}
...

我将cardHelper传递给OneCardViewController以便在那里使用。

但是,在OneCardViewController我尝试从card获得cards,我知道这些卡已从NSMutableDictionary转换为NSCFString

OneCardViewController界面:

@interface OneCardViewController : UIViewController {
    CardHelper* cardHelper;
    ...
}

@property (nonatomic, retain) CardHelper* cardHelper;

我在这里得到例外:

- (void) setUpTarotGame
{
    int arcaneNumber;
    arcaneNumber = [cardHelper GenerateArcaneNumber];
    NSString* number = [NSString stringWithFormat:@"%d", arcaneNumber];
    if (cardHelper == nil) {
        NSLog(@"cardHelper nil");
        return;
    }
    if (cardHelper.cards == nil)
    {
        NSLog(@"cards nil");
        return;
    }
    else
        NSLog(@"cards count = %d", [cardHelper.cards count]);
    currentCard = [cardHelper.cards objectForKey:number];

    [self setCardImageWithArcane:arcaneNumber];
}

此行引发异常:

currentCard = [cardHelper.cards objectForKey:number];

你知道为什么吗?

3 个答案:

答案 0 :(得分:2)

它没有被转换,它被释放,内存被用于其他东西。

在init方法中,您不会保留这些对象:

userLanguage = [NSString stringWithString:language];
cards = [NSMutableDictionary dictionaryWithCapacity: kNumCards];

尝试

userLanguage = [language copy];
cards = [NSMutableDictionary alloc] initWithCapacity:kNumCards];

代替。

答案 1 :(得分:2)

您没有保留对象,它们正在被释放,并且指针未指向重新使用相同内存的新对象。

考虑为您的项目使用ARC(自动保留计数)。使用ARC,编译器会处理保留计数,因此实际上不允许这样做。有一个重构将转换当前项目。

ARC的编程生活应该更加快乐。 : - )

答案 2 :(得分:1)

cards = [NSMutableDictionary dictionaryWithCapacity: kNumCards]; 

这会创建一个自动释放的对象。当你再次调用它时,它已被释放并分配给其他东西,在这种情况下是一个字符串。

您必须保留字典或创建非自动释放字典:

cards = [[NSMutableDictionary alloc] initWithCapacity:kNumCards];