0

これは私のCoreDataManagerClassです。

#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@interface RTC_CoreDataManager : NSObject
@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
  - (void)saveContext;
  - (NSURL *)applicationDocumentsDirectory;
  -(void)insertEntity:(NSString *)entityName arrayOfManagedObject:(NSMutableArray *)array;
  +(RTC_CoreDataManager *)shredInstance;
   @end

#import "RTC_CoreDataManager.h"
RTC_CoreDataManager *obj_RTC;
@implementation RTC_CoreDataManager

@synthesize managedObjectContext = __managedObjectContext;
@synthesize managedObjectModel = __managedObjectModel;
@synthesize persistentStoreCoordinator = __persistentStoreCoordinator;

 - (void)saveContext
 {
 NSError *error = nil;
  NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
if (managedObjectContext != nil) {
 if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {

           NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
           abort();
        }
   }
}

+(RTC_CoreDataManager *)shredInstance{
if (obj_RTC ==  nil) {
           obj_RTC = [[RTC_CoreDataManager alloc]init];
       }
        return obj_RTC;

    }
#pragma mark - Core Data stack


- (NSManagedObjectContext *)managedObjectContext
{
   if (__managedObjectContext != nil) {
        return __managedObjectContext;
  }

   NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
   if (coordinator != nil) {
       __managedObjectContext = [[NSManagedObjectContext alloc] init];
       [__managedObjectContext setPersistentStoreCoordinator:coordinator];
   }
   return __managedObjectContext;
}


- (NSManagedObjectModel *)managedObjectModel
{
    if (__managedObjectModel != nil) {
        return __managedObjectModel;
    }
    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"RTC" withExtension:@"momd"];
    __managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
    return __managedObjectModel;
}


- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
 {
     if (__persistentStoreCoordinator != nil) {
        return __persistentStoreCoordinator;
   }

    NSURL *storeURL = [[self applicationDocumentsDirectory]     URLByAppendingPathComponent:@"RTC.sqlite"];
    NSError *error = nil;
    if (![[NSFileManager defaultManager] copyItemAtURL:storeURL toURL:[NSURL alloc] error:&error]) {
        NSLog(@"Oops, could copy preloaded data");
    }

__persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    abort();
}

return __persistentStoreCoordinator;
}

#pragma mark - Application's Documents directory

// Returns the URL to the application's Documents directory.
- (NSURL *)applicationDocumentsDirectory
{
    return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}

-(void)insertEntity:(NSString *)entityName arrayOfManagedObject:(NSMutableArray *)array 
{
NSManagedObjectContext *backgroundMOC = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
for (id object in array)
 {

 [backgroundMOC performBlockAndWait:^
 {
 NSError *error;
 if (![__managedObjectContext save:&error]) 
 {
NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
}
}];
}

}

@end

そして、これは別のコントローラーの私のコードです。

    -(void)viewDidLoad
    {
     [super viewDidLoad];
     appDele_Obj = (RTC_AppDelegate *)[[UIApplication sharedApplication] delegate];
   appDele_Obj.entityArray=[[NSMutableArray alloc]init];

for (int i=0; i<10; i++)
{

    Survey *objSurvey = [NSEntityDescription
                         insertNewObjectForEntityForName:@"Survey"
                         inManagedObjectContext:[RTC_CoreDataManager shredInstance].managedObjectContext];        [objSurvey setFirstName:@"1"];
    [objSurvey setLastName:@"2"];
    [objSurvey setEmpId:@"3"];
    [objSurvey setLanguage:@"Hindi"];
    [objSurvey setCountry:@"India"];
    [objSurvey setSurveyNo:[NSNumber numberWithInt:2]];
    [[appDele_Obj entityArray] addObject:objSurvey];
    [objSurvey release];
}
//[objSurvey release];
[[RTC_CoreDataManager shredInstance] insertEntity:@"Survey" arrayOfManagedObject:[appDele_Obj entityArray]];
if ([[appDele_Obj entityArray]count]  >0) {
    [[appDele_Obj entityArray] removeAllObjects];

}
}

私の質問は、アプリケーションのクラッシュ
時にメソッド removeAllObjects を呼び出す場合です。 上記のアプローチで[appDele_Obj entityArray]呼び出せない理由。[[appDele_Obj entityArray] removeAllObjects];誰でもこのクラッシュを解決するのに役立ちます。

ありがとう。

4

1 に答える 1

1

これは、メモリの管理ミスの単純なケースです。これにより、自動解放されたオブジェクトが作成されます。

Survey *objSurvey = [NSEntityDescription
    insertNewObjectForEntityForName:@"Survey"
    inManagedObjectContext:[RTC_CoreDataManager shredInstance].managedObjectContext];

次に、これを行います。

[[appDele_Obj entityArray] addObject:objSurvey];
[objSurvey release];

ここに電話してはいけませんrelease。オブジェクトは自動解放されます。呼び出しreleaseは不要であるだけでなく、危険です。後で配列からオブジェクトを削除すると、配列内のすべてのオブジェクトを過剰に解放することになります。それがクラッシュの原因です。

コードからの他のいくつかのこと:

  1. save:ループを通過するたびに新しい変更を行う場合を除き、ループ内で管理オブジェクト コンテキストを呼び出す必要はありません。あなたのinsertEntity:arrayOfManagedObject:方法は、多くの不要な作業を行っています。

  2. の配列は、viewDidLoadあなたがしていることには必要ではなく、役に立ちません。オブジェクトを作成し、管理対象オブジェクト コンテキストに配置しました。これらのオブジェクトの属性の設定が完了したら、参照を保持する必要はありません。完了するまでオブジェクトを追加し続けてから、管理対象オブジェクトのコンテキストに保存するように指示します。

  3. 細かいことですが、シングルトンを作成するメソッドに名前を付けましたshredInstance。「シュレッド」は、その方法で行っていることとほぼ正反対です。あなたはおそらく意味しsharedInstanceた。

于 2013-03-05T17:37:05.930 に答える