2011-01-12 8 views
1

rssフィードからデータをインポートしようとしています。最初のレコードは正常に挿入されますが、2番目のレコードはEXC_BAD_ACCESS例外になります。コードを踏んでいくと、物事を理解することに近づかない。障害ポイントは、managedObjectContext saveメソッドの呼び出しにあります。コアデータでEXC_BAD_ACCESSの原因を特定できません

私はこれに助けていただきありがとうございます。

/* Workout.h */ 
#import <UIKit/UIKit.h> 
@class Workout; 

@interface WorkoutsController : UITableViewController <NSXMLParserDelegate> { 
    NSFetchedResultsController *_fetchedResultsController; 
    NSURLConnection *urlConnection; 
    NSMutableData *xmlData; 

    Workout *currentWorkout; 
    NSMutableString *title; 
    NSMutableString *link; 
    NSMutableString *details; 
    NSMutableString *currentElement; 
} 

@property (nonatomic, retain) NSFetchedResultsController *fetchedResultsController; 
@property (nonatomic, retain) NSURLConnection *urlConnection; 
@property (nonatomic, retain) NSMutableData *xmlData; 

@property (nonatomic, retain) Workout *currentWorkout; 
@property (nonatomic, retain) NSMutableString *title; 
@property (nonatomic, retain) NSMutableString *link; 
@property (nonatomic, retain) NSMutableString *details; 
@property (nonatomic, retain) NSMutableString *currentElement; 

@end 

/* Workout.m */ 
/** 
* Determine if the current element is an 'item' 
* <item> 
* <title>...</title> 
* <link>...</link> 
* <content:encoded>...</content:encoded> 
*/ 
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName 
             namespaceURI:(NSString *)namespaceURI 
             qualifiedName:(NSString *)qName 
              attributes:(NSDictionary *)attributeDict { 

    // determine when parser is inside an item element 
    if ([elementName isEqualToString:@"item"]) { 
     self.currentWorkout = [[Workout alloc] initWithEntity:[[self.fetchedResultsController fetchRequest] entity] 
           insertIntoManagedObjectContext:[self.fetchedResultsController managedObjectContext]]; 
    } 

    // only read child elements of the item element 
    if (self.currentWorkout != nil) { 
     if ([elementName isEqualToString:@"title"]) { 
      self.title = [[NSMutableString alloc] init]; 
      self.currentElement = title; 
     } 
     else if ([elementName isEqualToString:@"link"]) { 
      self.link = [[NSMutableString alloc] init]; 
      self.currentElement = link; 
     } 
     else if ([elementName isEqualToString:@"content:encoded"]) { 
      self.details = [[NSMutableString alloc] init]; 
      self.currentElement = details; 
     } 
    } 
} 

/** 
* Finished reading the tag content 
*/ 
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { 
    // only read child elements of the item element 
    if (self.currentWorkout != nil) { 
     [self.currentElement appendString:string]; 
    } 
} 

/** 
* Extract the text for the following tags 
* <item> 
* <title>...</title> 
* <link>...</link> 
* <content:encoded>...</content:encoded> 
*/ 
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName 
             namespaceURI:(NSString *)namespaceURI 
            qualifiedName:(NSString *)qName { 

    // determine if the item element is being closed 
    // if so save the workout 
    if ([elementName isEqualToString:@"item"]) { 
     self.currentWorkout.title = self.title; 
     self.currentWorkout.url = self.link; 
     self.currentWorkout.details = self.details; 

     NSLog(@"Completing: %@", self.currentWorkout.title); 

     NSError *error; 

     NSManagedObjectContext *moc = [self.fetchedResultsController managedObjectContext]; 

     /*** Line 206: Fails Here ***/ 
     if (![moc save:&error]) { 
      NSLog(@"Failed to save to data store: %@ - %@", 
        [error localizedDescription], [error userInfo]); 
     } 

     [self.currentElement release]; 
     self.currentElement = nil; 

     [self.title release]; 
     self.title = nil; 

     [self.link release]; 
     self.link = nil; 

     [self.details release]; 
     self.details = nil; 

     [self.currentWorkout release]; 
     self.currentWorkout = nil; 
    } 
} 

/* Backtrace */ 
(gdb) bt 
#0 0x027b6903 in objc_msgSend() 
#1 0x00000007 in ??() 
#2 0x023a2688 in _NSQLRow_dealloc_standard() 
#3 0x026730eb in __CFBasicHashRemoveValue() 
#4 0x0258a1e0 in CFBasicHashRemoveValue() 
#5 0x0259f7c8 in CFDictionaryRemoveValue() 
#6 0x02441724 in -[NSSQLCore managedObjectContextDidUnregisterObjectsWithIDs:]() 
#7 0x0243524a in -[NSPersistentStoreCoordinator(_NSInternalMethods) _informAffectedStoresOfInterestByChildContextInObjectsWithObjectIDs:withSelector:]() 
#8 0x0242e940 in -[NSPersistentStoreCoordinator(_NSInternalMethods) managedObjectContextDidUnregisterObjectsWithIDs:]() 
#9 0x02384396 in -[_PFManagedObjectReferenceQueue _processReferenceQueue:]() 
#10 0x023837f4 in -[NSManagedObjectContext(_NSInternalChangeProcessing) _processRecentChanges:]() 
#11 0x023bce55 in -[NSManagedObjectContext save:]() 
#12 0x000038e5 in -[WorkoutsController parser:didEndElement:namespaceURI:qualifiedName:] (self=0x633ca10, _cmd=0x178994, parser=0x632a0c0, elementName=0x634a850, namespaceURI=0x0, qName=0x0) at /Users/chris/Documents/Projects/iPhone/WorkoutApp/Classes/WorkoutsController.m:206 
#13 0x000f13a9 in _endElementNs() 
#14 0x02ae6ea7 in xmlParseXMLDecl() 
#15 0x02af1bb1 in xmlParseChunk() 
#16 0x000f0baa in -[NSXMLParser parse]() 
#17 0x00003352 in -[WorkoutsController connectionDidFinishLoading:] (self=0x633ca10, _cmd=0x17ce32, connection=0x6343510) at /Users/chris/Documents/Projects/iPhone/WorkoutApp/Classes/WorkoutsController.m:132 
#18 0x00059b96 in -[NSURLConnection(NSURLConnectionReallyInternal) sendDidFinishLoading]() 
#19 0x00059aef in _NSURLConnectionDidFinishLoading() 
#20 0x02c0d72f in URLConnectionClient::_clientDidFinishLoading() 
#21 0x02cd8fcf in URLConnectionClient::ClientConnectionEventQueue::processAllEventsAndConsumePayload() 
#22 0x02c02968 in URLConnectionClient::processEvents() 
#23 0x02c027e5 in MultiplexerSource::perform() 
#24 0x0263afaf in __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__() 
#25 0x0259939b in __CFRunLoopDoSources0() 
#26 0x02598896 in __CFRunLoopRun() 
#27 0x02598350 in CFRunLoopRunSpecific() 
#28 0x02598271 in CFRunLoopRunInMode() 
#29 0x02f3800c in GSEventRunModal() 
#30 0x02f380d1 in GSEventRun() 
#31 0x002c6af2 in UIApplicationMain() 
#32 0x000021b0 in main (argc=1, argv=0xbfffefdc) at /Users/chris/Documents/Projects/iPhone/WorkoutApp/main.m:14 
+0

私たちにお知らせください...あなたの実装ファイルの行番号206には何がありますか? –

+0

行206は、失敗場所としてマークされた行です。物事をより明確にするためにコードを更新しました。 – chris

答えて

1

私はあなたのクラッシュはここからであるかなり確信している:基本的に

[self.currentElement release]; 
    self.currentElement = nil; 

、そのようなすべての行が間違っている - 彼らは次のようになります。今

self.currentElement = nil; 

加えて、そのためには、プロパティを使って設定した変数も自動解放する必要があります。このコード(とそのようなすべてのコード)は間違っています:

 self.title = [[NSMutableString alloc] init]; 
     self.currentElement = title; 

それはのように見える必要があります:あなたは、後でコードが一緒に来た同じ可変文字列にcurrentElement、タイトルプロパティを指してcurrentElementとタイトルの両方を解放し、その後リリースされているためである何が起こっている

self.title = [NSMutableString string]; 
self.currentElement = title; 

self.propertyname = nilでもう一度、あなたは気違いのようなオブジェクトを過剰にリリースしました。

メモリルールは本当に簡単です。メソッドを終了した後に何かがオブジェクトを「保持」すると、そのオブジェクトは保持されるので、そうしないでください。

+0

:) [currentElement release]行を削除するとすべてが実行されますが、理由は不明です。これらは両方とも保持設定のプロパティであるため、これらのプロパティへの代入は保持回数を2回上回らないでしょうか?あなたが「すべてのラインが間違っている」と言ったら、タイトル、リンク、詳細を参照していますか?もしそうなら、リリースコールを削除してもメモリに問題はありませんか? – chris

+0

最後のコードスニペットの例では、文字列がオートリリースされていて、リリースコールを排除して動作するようになっているので、私はそれがどのように動作するかを見ることができます。最後の質問ですが、「propertyName = nilでもう一度解放する」と言うと、ポインタをnilに設定すると保持カウントが減少すると言っていますか? – chris

+0

はい、正確には、プロパティをnilに設定すると、実際には、指しているオブジェクトをリリースしてから、参照が消去されます。したがって、何かを解放し、それを保持しないプロパティを設定すると、オブジェクトが2回解放されます。 –

関連する問題