0

アプリが存続する限り必要な NSMutableArray を作成します。メイン クラスの @implementation の直後に、それを suseranArray と呼びましょう。この配列は、Vassal と呼ばれるクラスのいくつかのオブジェクトを保持します。家臣は単純に:

1) NSMutableString 2) 別の NSMutableString 3) NSMutableArray 4) 別の NSMutable 配列

作成された各 Vassal は、アプリの存続期間にも必要であり、変更されることはありません。

これらのオブジェクトは、.h ファイルで (保持) プロパティとして作成され、.m ファイルで合成され、init 関数でオブジェクト Vassal が作成されるたびに、それぞれに alloc+init が与えられます。各家臣には、データが入力され、宗主配列に格納されています。3番目の項目には常にいくつかの要素があり、バグが発生した後、空になるかどうかを確認する行を入れましたが、空になることはなく、人生は良いです.

さて、後で特定の Vassal オブジェクトが必要になったときに、その 3 番目のプロパティにアクセスしてそこにあるデータを取得しようとしますが、その配列が空になることもあります...どうにか消えたかどうかを確認しましたが、常にこれは、そのすぐ上の NSMutableString がアドレス 0x2319fb40 にあるためです (頭痛の種の後で 00000000 を期待していました)。何が起こっている?私の頭では、デフォルトで入れられたデータを保持する RETAINed オブジェクトを作成しています。そのオブジェクトは別のオブジェクトの中に入れられますが、どういうわけか配列内のデータが消えます。これにつながる可能性のあるシナリオは何ですか? お時間をいただきありがとうございます:)

注: 現在、開発のこの段階では、最後の配列は 1 つの項目を保持するだけであり、2 つの配列が「兄弟」であるにもかかわらず、1 つの項目が失われることはありません。

Vassal.h
@interface Vassal : NSObject
@property  (retain) NSMutableString *wordBody;
@property  (retain) NSMutableString *wordCode;
@property   (retain) NSMutableArray *wordRelations;
@property   (retain) NSMutableArray *wordLinks;
@end

Vassal.m
@implementation Vassal:NSObject
@synthesize wordBody;
@synthesize wordCode;
@synthesize wordRelations;
@synthesize wordLinks;
-(NSObject*) init
{
    if(self=[super init])
    {
        wordBody=[[NSMutableString alloc] init];
        wordCode=[[NSMutableString alloc] init];
        wordRelations=[[NSMutableArray alloc] init];
        wordLinks=[[NSMutableArray alloc] init];
    }
    return self;
}

//Somewhere in Suseran:
-(void)fillStuff
{
    ...
    Vassal *vassal=[Vassal new];
    for (int i=0;i<[originalDataString length];i++)
    {
        ...
        [vassal.wordRelations addObject:anItem];
        ...
    }
    int errorTest=[vassal.wordRelations count];
    if (errorTest==0)
    {
         //breakpoint here. Program NEVER comes here
    }
    [bigArrayOfVassals addObject:vassal];
}
//these arrays are never touched again but here:
-(void) getVassalstuff:(NSMutableString*)codeOfDesiredVassal
{
    Vassal *aVassal;
    for (int i=0;i<[bigArrayOfVassals count];i++)
    {
            aVassal=bigArrayOfVassals[i];
            if ([codeOfDesiredVassal isEqualToString:aVassal.wordCode)
            {
                  int errorTest=[aVassal.wordRelations count];
                  if (errorTest==0)
                  {
                         //yay! this breakpoint sometimes is hit, sometimes not,
                         //depending on code's mood. Why is this happening to me? :,(
                  }
            }
    }
}
4

1 に答える 1

1

変更可能なプロパティがあり (特定の場合を除いて、それ自体は悪い考えです)、それらを保持していることがわかります。

可変性とは、配列を他の配列に基づいてプロパティとして設定した場合、元の配列が変更されると、プロパティ内の配列も変更されることを意味します。コードを表示していないため、元の配列を空にして、プロパティとして持っている配列を変更している可能性があります。

ソリューション:

私の推奨する解決策は、これらのクラスの不変バージョンをプロパティに使用することです。NSString、NSArray、および保持の代わりにコピーを使用

mutableCopy2 番目の解決策は、プロパティを変更可能のままにしておくことですが、渡すオブジェクトのを格納するカスタム セッターを各プロパティに記述します。

どちらの場合も、プロパティはプロパティの設定に使用されるオブジェクトのコピーになるため、オブジェクトがクラス外で変更されても、クラスのプロパティには影響しません。

コメントの後に追加するように編集

あなたの財産を次のように宣言する場合

@property (copy) NSArray wordRelations;

あとは簡単に書くと

vassal wordArray = tempArray;

同じことを行い、よりクリーンで読みやすくなります..

于 2013-08-22T00:38:43.903 に答える