0

prepareResultsFromResultSetコード(2.5MB)内のメモリリークをデバッグしようとしていますが、内の_を指しているようNSFetchedResultsControllerです。2つのviewController(AとB)があり、viewControllerBはviewControllerAからnavigationControllerにプッシュされます。

BIでは、次 のようにNSFetchRequest使用を実行していますNSFetchedResultsController

@property (nonatomic, retain) NSFetchedResultsController *fetchedResultsController;
@property (nonatomic, retain) NSString *sMapSlug;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil andMapSlug: (NSString *)slug;

.m

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil andMapSlug: (NSString *)slug
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
        self.sMapSlug = [NSString stringWithString:slug];
    }
    return self;
}
- (NSFetchedResultsController *)fetchedResultsController {

    if (_fetchedResultsController != nil)
        return _fetchedResultsController;

    Singleton *singleton = [Singleton sharedSingleton];

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"DescriptionEntity" inManagedObjectContext:[singleton managedObjectContext]];
    [fetchRequest setEntity:entity];

    NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"map.sName" ascending:NO];
    [fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];
    NSPredicate *myPredicate = [NSPredicate predicateWithFormat:@"map.sSlug LIKE %@", self.sMapSlug];
    [fetchRequest setFetchBatchSize:8];
    [fetchRequest setPredicate:myPredicate];

    // Finally check the results
    NSError *error;
    NSArray *fetchedObjects = [[singleton managedObjectContext] executeFetchRequest:fetchRequest error:&error];
    for (DescriptionEntity *desc in fetchedObjects)
    {
        NSLog(@"Maps present in database: %@", desc.map.sName);
    }        

    NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[singleton managedObjectContext] sectionNameKeyPath:nil cacheName:@"Test1"];
    self.fetchedResultsController = theFetchedResultsController;
    self.fetchedResultsController.delegate = self;
    //[self.fetchedResultsController performFetch:NULL];
    [theFetchedResultsController release];
    [fetchRequest release];
    [sort release];

    return _fetchedResultsController;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
    [self.fetchedResultsController fetchRequest];
}

fetchRequestを使用してすべてが正常に読み込まれ、必要に応じてデータにアクセスできますが、今のところこれを取り出しているので、からのデータNSFetchedRequestControllerが使用されていないことがわかります。ナビゲーションスタックに戻ると、コントローラーBのdeallocが呼び出され、次のように実行します。

- (void)dealloc {
    self.fetchedResultsController.delegate = nil;
    [_fetchedResultsController release];
    [sMapSlug release];

    [super dealloc];
}

Instruments内でこれのヒープショットを撮ると、deallocが呼び出された後も次のデータが残っていることがわかります。

ここに画像の説明を入力してください

コントローラBに戻ると、このメモリの別のセットが追加され、削除されることはありません。ただし、これを3回実行しても、金額は増加しません。ある種のキャッシュが行われていると思いますが、このデータを削除する方法や、を正しく割り当て解除する方法を教えてもらえますかNSFetchedResultsController

さらに詳しい情報が必要な場合は、お気軽にお問い合わせください。

4

2 に答える 2

2

通常、CoreDataのメモリ管理について心配する必要はありません。はい、内部ではキャッシュメカニズムが関係しています。

とにかく、メモリを「閉じる」には2つの異なる方法があります。

1つ目はrefreshObject:mergeChanges:メソッドです。それに渡すとNO、オブジェクトグラフを整理することができます。つまり、ストアに保存されていない変更されたデータはすべて破棄されます。

オーバーライドwillTurnIntoFaultdidTurnIntoFaultて、動作を確認します。

もう1つはreset、管理されたコンテキストを呼び出すことです。明らかに、これにより、コンテキストに含まれるすべてのオブジェクトが削除されます。

お役に立てば幸いです。

于 2013-01-28T22:40:00.613 に答える
0

自分のオブジェクトであっても、自分でdeallocを呼び出すことは絶対にしないでください。これは、システムが自分で行うことです。

于 2013-01-29T13:13:46.490 に答える