实现收藏有很多方式,我在自己练习的项目中用CoreData实现了一下收藏功能,注释很少,算是自己做的一个笔记。
首先创建一个工具类继承NSObject,在里面实现所需要的方法.
工具类的.h文件:
<pre>
typedef NS_ENUM(NSUInteger, SelectInEntities) {
InEntities,
NotInEntities,
SelectError,
};
typedef NS_ENUM(NSUInteger, Entities) {
   NewsEntity,
   PostEntity,
  TypeEntity,
  ForumEntity,
};
@interface BFFCoreDataManager : NSObject
// 管理对象上下文(管理者)
@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
// 管理对象模型(表结构)
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
// 持久化存储协调器(助理)
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
// 保存上下文(保存对数据的修改)
- (void)saveContext;
 // 沙盒路径
- (NSURL *)applicationDocumentsDirectory;
//-(SelectInEntities)isInEntities:(Entities)entities
//                    Model:(id)model;
+(BFFCoreDataManager *)shareBFFCoreDataManager;
- (id)isInEntities:(Entities)entities model:(id)model;
- (BOOL)has:(NSMutableDictionary *)dic arr:(NSArray *)array;
 ///地方分会
- (BOOL)hass:(NSMutableDictionary *)dic arr:(NSArray *)array;
 ///推荐论坛
- (BOOL)hasss:(BFFDiscussModel *)model arr:(NSArray *)array;
- (BOOL)haspost:(BFFSelectModel *)model arr:(NSArray *)array;
- (BOOL)state:(NSArray *)arr url:(NSString *)url;
- (BOOL)states:(NSArray *)arr ids:(NSString *)ids;
- (id)myModel:(id)model;
 @property (nonatomic, strong) BFFCoreDataManager *manager;
 @end</pre>
工具类的.m文件
<pre>
@implementation BFFCoreDataManager
#pragma mark - Core Data stack
@synthesize managedObjectContext = _managedObjectContext;
@synthesize managedObjectModel = _managedObjectModel;
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
- (BFFCoreDataManager *)shareBFFCoreDataManager
 {
 /// 单例不能释放
 static BFFCoreDataManager *manager = nil;
 // 保证线程安全, 该方法只走一次
 static dispatch_once_t onceToken;
 dispatch_once(&onceToken, ^{
 manager = [BFFCoreDataManager new];
 });
 return manager;
 }
 // 获取到沙盒的Document路径
- (NSURL *)applicationDocumentsDirectory { 
 // The directory the application uses to store the Core Data store file. This code uses a directory named "com.lanou3g.TheWorldCar" in the application's documents directory.
 return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
 }
- (NSManagedObjectModel *)managedObjectModel { 
 // The managed object model for the application. It is a fatal error for the application not to be able to find and load its model.
 if (_managedObjectModel != nil) {
 return _managedObjectModel;
 }
 NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"TheWorldCar" withExtension:@"momd"];
 _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
 return _managedObjectModel;
 }
- 
(NSPersistentStoreCoordinator *)persistentStoreCoordinator { 
 // The persistent store coordinator for the application. This implementation creates and returns a coordinator, having added the store for the application to it.
 if (_persistentStoreCoordinator != nil) {
 return _persistentStoreCoordinator;
 }// Create the coordinator and store _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; 
 NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"TheWorldCar.sqlite"];
 NSError *error = nil;
 NSString *failureReason = @"There was an error creating or loading the application's saved data.";NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil]; if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) { 
 // Report any error we got.
 NSMutableDictionary *dict = [NSMutableDictionary dictionary];
 dict[NSLocalizedDescriptionKey] = @"Failed to initialize the application's saved data";
 dict[NSLocalizedFailureReasonErrorKey] = failureReason;
 dict[NSUnderlyingErrorKey] = error;
 error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:9999 userInfo:dict];
 // Replace this with code to handle the error appropriately.
 // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
 NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
 abort();
 }return _persistentStoreCoordinator; 
 }
- 
(NSManagedObjectContext *)managedObjectContext { 
 // Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.)
 if (_managedObjectContext != nil) {
 return _managedObjectContext;
 }NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; 
 if (!coordinator) {
 return nil;
 }
 _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
 [_managedObjectContext setPersistentStoreCoordinator:coordinator];
 return _managedObjectContext;
 }
pragma mark - Core Data Saving support
- (void)saveContext { 
 NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
 if (managedObjectContext != nil) {
 NSError *error = nil;
 if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
 // Replace this implementation with code to handle the error appropriately.
 // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
 NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
 abort();
 }
 }
 }
- 
(id)myModel:(id)model{ 
 NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
 NSEntityDescription *entity = [NSEntityDescription entityForName:@"Type" inManagedObjectContext:self.managedObjectContext];
 [fetchRequest setEntity:entity];
 NSError *error = nil;
 NSArray *fetchedObjects = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
 if (fetchedObjects == nil) {
 NSLog(@"%@", error);
 }
 BFFCollectModel *newsModel = model;
 for (Type *type in fetchedObjects) {
 if ([type.name isEqualToString:newsModel.name]) {
 return type;
 } else {
 return nil;
 }
 }return nil; 
 }
// 判断是否在数据库中
- 
(id)isInEntities:(Entities)entities model:(id)model 
 {
 switch (entities) {
 case NewsEntity:
 {
 NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
 NSEntityDescription *entity = [NSEntityDescription entityForName:@"News" inManagedObjectContext:self.managedObjectContext];
 [fetchRequest setEntity:entity];
 NSError *error = nil;
 NSArray *fetchedObjects = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
 if (fetchedObjects == nil) {
 NSLog(@"%@", error);
 }
 BFFNewsModel *newsModel = model;
 for (News *news in fetchedObjects) {
 if ([news.newsLink isEqualToString:newsModel.newsLink]) {
 return news;
 }
 }
 return nil;
 }
 break;
 case PostEntity:
 {
 NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
 NSEntityDescription *entity = [NSEntityDescription entityForName:@"Post" inManagedObjectContext:self.managedObjectContext];
 [fetchRequest setEntity:entity];
 NSError *error = nil;
 NSArray *fetchedObjects = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
 if (fetchedObjects == nil) {
 NSLog(@"%@", error);
 }
 BFFHotModel *hot = model;
 for (Post *post in fetchedObjects) {
 if ([post.postLink isEqualToString:hot.postLink]) {
 return post;
 }
 }
 return nil;
 }
 break;
 case TypeEntity:
 {} break; case ForumEntity: { NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; NSEntityDescription *entity = [NSEntityDescription entityForName:@"Line" inManagedObjectContext:self.managedObjectContext]; [fetchRequest setEntity:entity]; NSError *error = nil; NSArray *fetchedObjects = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error]; if (fetchedObjects == nil) { NSLog(@"%@", error); } BFFCarDetailModel *carDetail = model; for (Line *line in fetchedObjects) { if ([line.seriesId isEqualToString:[NSString stringWithFormat:@"%@", carDetail.seriesId]]) { return line; } } return nil; } break; default: break;} 
 return nil;
 }
//爱车俱乐部.人车生活
- (BOOL)has:(NSMutableDictionary *)dic arr:(NSArray *)array{
 NSNumber *num = dic[@"forumId"];
 for (Forum *forum in array) {
 if ([forum.postId isEqualToString:num.description]) {
 return YES;
 }
 }
 return NO;
 }
///地方分会
- (BOOL)hass:(NSMutableDictionary *)dic arr:(NSArray *)array{
 NSNumber *num = dic[@"id"];
 for (Forum *forum in array) {
 if ([forum.postId isEqualToString:num.description]) {
 return YES;
 }
 }
 return NO;
 }
///论坛推荐
- (BOOL)hasss:(BFFDiscussModel *)model arr:(NSArray *)array{
 for (Forum *forum in array) {
 if ([forum.postId isEqualToString:model.forumId.description]) {
 return YES;
 }
 }
 return NO;
 }
///帖子收藏
- (BOOL)haspost:(BFFSelectModel *)model arr:(NSArray *)array{
 for (Post *post in array) {
 if ([post.postLink isEqualToString:model.postLink]) {
 return YES;
 }
 }
 return NO;
 }
///改变帖子收藏按钮图标
- (BOOL)state:(NSArray *)arr url:(NSString *)url{
 for (Post *post in arr) {
 if ([post.postLink isEqualToString:url]) {
 return YES;
 }
 }
 return NO;
 }
///改变论坛收藏按钮图标
- (BOOL)states:(NSArray *)arr ids:(NSString *)ids{
 for (Forum *forum in arr) {
 if ([forum.postId.description isEqualToString:ids]) {
 return YES;
 }
 }
 return NO;
 }
/**-(SelectInEntities)isInEntities:(Entities)entities
Model:(id)model
{
switch (entities) {
case NewsEntity:
{
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"News" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
NSError *error = nil;
NSArray *fetchedObjects = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
if (fetchedObjects == nil) {
NSLog(@"%@", error);
}
BFFNewsModel *newsModel = model;
        for (News *news in fetchedObjects) {
            if ([news.newsLink isEqualToString:newsModel.newsLink]) {
                return InEntities;
            } else {
                return NotInEntities;
            }
        }
    }
        break;
        case PostEntity:
    {
   }
        break;
        case LineEntity:
    {
   }
        break;
        case ForumEntity:
    {
    }
       break;
   default:
        break;
}
return SelectError;
}
@end
*/
</pre>
接下来在收藏页面创建一个Button实现收藏
<pre>
- 
(void)collectionBut:(id)sender{ BFFCollectModel *model = self.tempModel; 
 if ([self.manager myModel:model] == nil) {
 Type *type = [NSEntityDescription insertNewObjectForEntityForName:@"Type" inManagedObjectContext:self.manager.managedObjectContext];
 type.name = model.name;
 type.priceRange = model.priceRange;
 type.photo = model.photo;
 type.uid = [NSString stringWithFormat:@"%@", model.uid];
 [self.manager saveContext];self.collectLabel.text = @"已经收藏"; self.collectLabel.hidden = NO; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ self.collectLabel.hidden = YES; });} else { 
 [self.manager.managedObjectContext deleteObject:[self.manager myModel:model]];
 [self.manager saveContext];
 self.collectLabel.text = @"已取消收藏";
 self.collectLabel.hidden = NO;
 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
 self.collectLabel.hidden = YES;
 });
 }
 }
///在我的收藏页面把数据取出
- 
(void)createLineData 
 {
 self.typeArr = [NSMutableArray array];
 NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
 NSEntityDescription *entity = [NSEntityDescription entityForName:@"Type" inManagedObjectContext:self.manager.managedObjectContext];
 [fetchRequest setEntity:entity];
 NSError *error = nil;
 NSArray *fetchedObjects = [self.manager.managedObjectContext executeFetchRequest:fetchRequest error:&error];if (fetchedObjects == nil) { 
 NSLog(@"%@", error);
 }
 [self.typeArr addObjectsFromArray:fetchedObjects];
 [self.tableView reloadData];
}
///这些数据都铺在了tableView上接下来实现删除的操作
- 
(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 
 {
 if (editingStyle == UITableViewCellEditingStyleDelete) {
 if (self.titleSegment.selectedSegmentIndex == 0) {
 News *news = self.newsArr[indexPath.row];
 [self.manager.managedObjectContext deleteObject:news];
 [self.manager saveContext];
 [self.newsArr removeObjectAtIndex:indexPath.row];
 [self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationLeft];
 }else if (self.titleSegment.selectedSegmentIndex == 1){
 Post *post = self.postArr[indexPath.row];
 [self.manager.managedObjectContext deleteObject:post];
 [self.manager saveContext];
 [self.postArr removeObjectAtIndex:indexPath.row];
 [self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationLeft];
 }else if (self.titleSegment.selectedSegmentIndex == 2){
 Forum *forum = self.forumArr[indexPath.row];
 [self.manager.managedObjectContext deleteObject:forum];
 [self.manager saveContext];
 [self.forumArr removeObjectAtIndex:indexPath.row];
 [self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationLeft];}else{ Type *type = self.typeArr[indexPath.row]; [self.manager.managedObjectContext deleteObject:type]; [self.manager saveContext]; [self.typeArr removeObjectAtIndex:indexPath.row]; [self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationLeft]; }} 
 [self.tableView reloadData];
 }</pre>这些就是实现收藏的过程 










