0

iOS アプリでは、いくつかのバックグラウンド スレッドを開始して、REST サービスから返された XML を処理しています。

PeopleParser.m の [self.names addObject: name] コード行で断続的なクラッシュを経験しているユーザーが何人かいます。クラッシュ ログには理由は示されず、クラッシュしたコード行のみが示されます。クラッシュを再現できないため、メモリに関連していると想定しています。for ループが終了する前に、おそらくメイン スレッド プールによって *xml オブジェクトが解放されている可能性はありますか? バックグラウンド スレッドで自動解放プールを宣言していないことに注意してください。

Fetcher.m

-(void) peopleFetchComplete:(ASIHTTPRequest *)theRequest {

    dispatch_async( backgroundQueue, ^{
       PeopleParser *xmlParse = [[PeopleParser alloc] initWithContext:[self managedObjectContext]];
       [xmlParse parseXMLData:[theRequest responseData] parseError:&parseError];
       [xmlParse release];
    });
}

PeopleParser.h

@interface PeopleParser : NSObject {
    NSMutableArray *names;
    ...
}

-(void)parseXMLData:(NSData *)data parseError:(NSError **)error;

@property (retain, nonatomic) NSMutableArray *names;

PeopleParser.m

-(id)initWithContext:(NSManagedObjectContext *)managedObjContext{
    self = [super init];
    self.managedObjectContext = managedObjContext;
    names = [[NSMutableArray alloc] init];
    return self;
}

-(void)dealloc{
    [names release];
    [managedObjectContext release];
}

@synthesize names;

-(void)parseXMLData {

    //documentWithData returns an autorelease object
    SMXMLDocument *xml = [SMXMLDocument documentWithData:someNSData error:nil];
    NSArray *people = [[document root] children];

    for (SMXMLElement *element in people) {
        NSString *name = [element attributeNamed:@"personName"];
        [self.names addObject: name];  //CRASHES HERE occasionally 
    }

    //do additional stuff with the data
    ...
}

クラッシュログ

例外の種類: EXC_CRASH (SIGABRT) 例外コード: 0x0000000000000000、0x0000000000000000 クラッシュしたスレッド: 7

最後の例外バックトレース:

0 CoreFoundation 0x3465229e __exceptionPreprocess + 158

1 libobjc.A.dylib 0x3c37a97a objc_exception_throw + 26

2 CoreFoundation 0x3459c8d4 -[__NSArrayM insertObject:atIndex:] + 764

3 MyApp 0x000fee36 -[PeopleParser parseXMLData:parseError:] (PeopleParser.m:62)

4 MyApp 0x000e9b4c __50-[Fetcher peopleFetchComplete:]_block_invoke (Fetcher.m:818)

4

1 に答える 1

1

ブロックが実行される前に「self.names」の割り当てが解除される可能性があります。ユーザーが戻ることができないように、ブロック操作をキャンセルするか、(ロード画面で画面をブロックすることによって) このクラスが割り当て解除されないように保護してください。

たとえば、unloadView やそのような場所で発生する可能性があります (さらにコードを貼り付けると、より正確になる可能性があります)。

それに基づいて、insertObject メソッドから例外が呼び出されると思います。これは、「nil」オブジェクトを挿入しようとしている可能性が最も高いことを意味します。配列に追加する前に if(name) { } を追加してみてください。その場合、XML ファイルに問題がある可能性があります。

于 2013-09-10T16:16:02.390 に答える