NSMutableDictionary преобразован в __NSCFString - PullRequest
1 голос
/ 14 декабря 2011

Я разрабатываю приложение для 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];
}

CardHelper, определенный в ViewController:

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

Я передаю cardHelper в OneCardViewController для использования там.OneCardViewController Я пытаюсь получить card из cards, получаю, что карты преобразованы из NSMutableDictionary в NSCFString.

Интерфейс OneCardViewController:

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

@property (nonatomic, retain) CardHelper* cardHelper;

Iполучите здесь исключение:

- (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 ]

2 голосов
/ 14 декабря 2011

Вы не сохраняете объекты, они освобождаются, и указатели не указывают на новые объекты, которые повторно используют ту же память.

Рассмотрите возможность использования ARC (автоматического сохранения счета) для вашего проекта. С ARC компилятор заботится о сохранении счетчиков, поэтому вам не нужно, на самом деле это не разрешено. Существует рефакторинг, который преобразует текущий проект.

Ваша жизнь программирования должна быть намного счастливее с ARC. : -)

2 голосов
/ 14 декабря 2011

Он не конвертируется, он освобождается и память используется для чего-то другого.

В вашем методе init вы не сохраняете эти объекты:

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

Попробуйте

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

вместо.

1 голос
/ 14 декабря 2011
cards = [NSMutableDictionary dictionaryWithCapacity: kNumCards]; 

Это создает автоматически выпущенный объект. К тому времени, когда вы вызываете его снова, он освобождается и присваивается чему-то другому, в данном случае - строке.

Вы должны сохранить словарь или создать неавторизованный:

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