1

iOS4アプリケーションを開発しています。

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(私のアプリのメインView Controller)と呼ばれるクラスで作成されます。このビューコントローラーから、別のビューコントローラーを表示します。

- (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を取得しようとすると、カードがからに変換されたことがわかります。cardcardsNSMutableDictionaryNSCFString

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

なぜなのかご存知ですか?

4

3 に答える 3

2

変換されておらず、割り当てが解除されており、メモリが他の目的で使用されています。

initメソッドでは、これらのオブジェクトを保持していません。

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

試す

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

代わりは。

于 2011-12-14T11:21:24.893 に答える
2

オブジェクトを保持しておらず、割り当てが解除されており、ポインタが同じメモリを再利用している新しいオブジェクトを指していません。

プロジェクトにARC(自動保持カウント)を使用することを検討してください。ARCを使用すると、コンパイラが保持カウントを処理するため、保持する必要はありません。実際、許可されていません。現在のプロジェクトを変換するリファクタリングがあります。

あなたのプログラミング生活はARCではるかに幸せになるはずです。:-)

于 2011-12-14T12:06:08.170 に答える
1
cards = [NSMutableDictionary dictionaryWithCapacity: kNumCards]; 

これにより、自動解放されたオブジェクトが作成されます。もう一度呼び出すと、リリースされて別の何か(この場合は文字列)に割り当てられています。

辞書を保持するか、自動リリースされていない辞書を作成する必要があります。

cards = [[NSMutableDictionary alloc] initWithCapacity:kNumCards]; 
于 2011-12-14T11:21:36.713 に答える