2019-04-13 11:00:14 正式開始寫簡書,為了記錄自己的學(xué)習(xí)經(jīng)歷,同時也分享自己的學(xué)習(xí)成果。當(dāng)然有不對的地方非常歡迎大家提出,這樣既能提高自己,也能防止誤導(dǎo)別人╮( ̄▽ ̄)╭
OK,進(jìn)入正題:
1.UserDefualt
最簡單的數(shù)據(jù)存儲方式了,直接上代碼
//UserDefualt
NSMutableArray *mutArr = [[NSMutableArray alloc] initWithObjects:@"1", @"2", nil];
NSArray *arr = [NSArray array];
//1.UserDefualt存儲數(shù)據(jù)
[[NSUserDefaults standardUserDefaults] setObject:mutArr forKey:@"myData"];
arr = [[NSUserDefaults standardUserDefaults] valueForKey:@"myData"];
NSLog(@"arr = %@ \n", arr);
[mutArr addObject:@"3"];
[[NSUserDefaults standardUserDefaults] setObject:mutArr forKey:@"myData"];
arr = [[NSUserDefaults standardUserDefaults] valueForKey:@"myData"];
NSLog(@"arr = %@ \n", arr);
2.操作plist文件
對plist文件操作:需要獲取文件存儲路徑后創(chuàng)建.plist文件,之后用系統(tǒng)提供的NSFileManager對文件進(jìn)行操作,文件可以存在系統(tǒng)沙盒目錄下的Document或者Cache文件,這里選擇Document。
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"testLocalStorageData.plist"];
NSLog(@"path = %@ \n", path);
NSFileManager *fm = [NSFileManager defaultManager];
[fm createFileAtPath:path contents:nil attributes:nil];
//寫入
NSDictionary *dic = @{@"value1":@"key1", @"value2":@"key2"};
[dic writeToFile:path atomically:YES];
//讀出
NSDictionary *dicc = [NSDictionary dictionaryWithContentsOfFile:path];
NSLog(@"dicc = %@ \n", dicc);
3.解歸檔
解歸檔能夠存儲對象數(shù)據(jù),需要實現(xiàn)<NSCoding>或者<NSSecureCoding>協(xié)議,后者有一定加密措施。
.h文件
@interface TestClass : NSObject <NSSecureCoding> //解歸檔遵守NSCoding協(xié)議
.m文件
#pragma mark -NSSecureCoding方法實現(xiàn)
- (void)encodeWithCoder:(nonnull NSCoder *)aCoder {
[aCoder encodeObject:self.test1 forKey:@"test1"];
[aCoder encodeObject:self.test2 forKey:@"test2"];
[aCoder encodeObject:self.test3 forKey:@"test3"];
}
- (nullable instancetype)initWithCoder:(nonnull NSCoder *)aDecoder {
if (self == [super init]) {
self.test1 = [aDecoder decodeObjectForKey:@"test1"];
self.test2 = [aDecoder decodeObjectForKey:@"test2"];
self.test3 = [aDecoder decodeObjectForKey:@"test3"];
}
return self;
}
//加密協(xié)議需要實現(xiàn)下面的方法
+ (BOOL)supportsSecureCoding {
return YES;
}
使用:
TestClass *myclass = [TestClass new];
myclass.test1 = @"123";
myclass.test2 = @"456";
myclass.test3 = @"789";
NSLog(@"myclass = %@", myclass.test1);
NSString *archPath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0];
NSString *archFilePath = [archPath stringByAppendingPathComponent:@"archData.data"];
NSLog(@"----------%@", NSStringFromClass(myclass.class));
NSError *error;
//iOS12.0棄用
//[NSKeyedArchiver archiveRootObject:myclass toFile:archFilePath];
//歸檔
NSData *archData = [NSKeyedArchiver archivedDataWithRootObject:myclass requiringSecureCoding:YES error:&error];
NSLog(@"archData = %@", archData);
if (error) {
NSLog(@"archError : %@", error);
}else{
[archData writeToFile:archFilePath atomically:YES];
}
//解檔
NSData *unarch = [[NSData alloc] initWithContentsOfFile:archFilePath];
TestClass *content = [NSKeyedUnarchiver unarchivedObjectOfClass:NSClassFromString(@"TestClass") fromData:unarch error:&error];
if (error){
NSLog(@"unarchError->%@", error);
}else{
NSLog(@"content = %@", content.test1);
}
4.CoreData
用來存儲數(shù)據(jù)形態(tài)更復(fù)雜的數(shù)據(jù),首先創(chuàng)建.xcdatamodeld文件,具體步驟:NewFile->DataModel->名字->創(chuàng)建。
CoreData.png
封裝CoreData方法為JCCoreDataManager
#import "JCCoreDataManager.h"
#define JC_CHECK_NSSTRING(str) ((str == nil) || ([str isEqualToString: @""]) || (str == NULL) || ([str isKindOfClass:[NSNull class]]))
@interface JCCoreDataManager(){
NSString *path;
NSString *dbFolderPath;
NSError *error;
}
/**
數(shù)據(jù)模型
*/
@property (nonatomic, strong) NSManagedObjectModel *objectModel;
/**
管理數(shù)據(jù)的對象
*/
@property (nonatomic, strong) NSManagedObjectContext *objectContext;
/**
持久化數(shù)據(jù)
*/
@property (nonatomic, strong) NSPersistentStoreCoordinator *coordinator;
@end
@implementation JCCoreDataManager
static JCCoreDataManager *manager = nil;
#pragma mark - 單例
+ (instancetype)sharedInstanceManager{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
manager = [[JCCoreDataManager alloc] init];
});
return manager;
}
- (instancetype)init
{
self = [super init];
if (self) {
//文件路徑
path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
dbFolderPath = [path stringByAppendingPathComponent:@"CoreData"];
NSError *error;
//創(chuàng)建托管對象模型
NSURL *url = [[NSBundle mainBundle] URLForResource:@"TestModel" withExtension:@"momd"];
_objectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:url];
//創(chuàng)建持久化協(xié)調(diào)器
_coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:_objectModel];
//創(chuàng)建本地數(shù)據(jù)庫文件
[_coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[self dbPath] options:nil error:&error];
//創(chuàng)建托管對象上下文
_objectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[_objectContext setPersistentStoreCoordinator:_coordinator];
}
return self;
}
/**
獲取數(shù)據(jù)庫路徑
@return NSURL
*/
- (NSURL *)dbPath {
NSError *error = nil;
if (![self checkPathExist]) {
[[NSFileManager defaultManager] createDirectoryAtPath:dbFolderPath withIntermediateDirectories:YES attributes:nil error:&error];
}
if (error){
NSLog(@"創(chuàng)建CoreManager文件失敗,error---->%@ \n", error);
return nil;
}
NSURL *dbUrl = [[NSURL fileURLWithPath:dbFolderPath] URLByAppendingPathComponent:@"myDB.sqlite"];
return dbUrl;
}
-(BOOL) checkPathExist{
return [[NSFileManager defaultManager] fileExistsAtPath:dbFolderPath];
}
#pragma mark - 刪除數(shù)據(jù)庫
+ (NSString *)deleteCoreData{
NSString *documentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSString *fileFolderPath = [documentPath stringByAppendingPathComponent:@"CoreData"];
NSError *error;
if ([[NSFileManager defaultManager] fileExistsAtPath:fileFolderPath]){
[[NSFileManager defaultManager] removeItemAtPath:fileFolderPath error:&error];
}else{
return @"沒有數(shù)據(jù),請先創(chuàng)建";
}
if (error){
return [NSString stringWithFormat:@"刪除失敗,error--->%@", error];
}
return @"刪除成功";
}
//=============數(shù)據(jù)庫操作===============//
#pragma mark -獲取數(shù)據(jù)模型
+ (NSManagedObject *)getManagedObjectWithEntityName:(NSString *)entityName{
NSManagedObject *managedObject = [NSEntityDescription insertNewObjectForEntityForName:entityName inManagedObjectContext:[JCCoreDataManager sharedInstanceManager].objectContext];
return managedObject;
}
#pragma mark -存儲數(shù)據(jù)
+ (NSString *)save{
JCCoreDataManager *manager = [JCCoreDataManager sharedInstanceManager];
if (![manager checkPathExist]) {
//manager = [[JCCoreDataManager alloc] init];
[manager.coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[manager dbPath] options:nil error:nil];
}
NSError *saveError = nil;
if ([manager.objectContext save:&saveError]) {
return @"存儲成功";
}else{
return [NSString stringWithFormat:@"存儲失敗,error->%@", saveError];
};
}
#pragma mark -更新數(shù)據(jù)
+ (BOOL)updateManagedObject:(NSManagedObject *)managedObject{
[[JCCoreDataManager sharedInstanceManager].objectContext refreshObject:managedObject mergeChanges:YES];
return [JCCoreDataManager save];
}
#pragma mark -查找數(shù)據(jù)
+ (NSArray *)searchCoreDataWithEntityName:(NSString *)entityName andAttribute:(NSString *)attribute andSelectName:(NSString *)searchName sorting:(NSString *)sortAttribute isAsending:(BOOL)isAsending{
NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:[JCCoreDataManager sharedInstanceManager].objectContext];
//創(chuàng)建fetch請求
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
fetchRequest.entity = entity;
//一次獲取全部數(shù)據(jù)
[fetchRequest setFetchBatchSize:0];
NSSortDescriptor *nameDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES];
NSSortDescriptor *ageDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"age" ascending:YES];
NSSortDescriptor *bloodTypeDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"bloodType" ascending:YES];
if (JC_CHECK_NSSTRING(sortAttribute) || ([sortAttribute isEqualToString:@"name"])) {
// NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:sortAttribute ascending:isAsending];
fetchRequest.sortDescriptors = @[nameDescriptor, ageDescriptor, bloodTypeDescriptor];
}else if ([sortAttribute isEqualToString:@"age"]){
fetchRequest.sortDescriptors = @[ageDescriptor, nameDescriptor, bloodTypeDescriptor];
}else{
fetchRequest.sortDescriptors = @[bloodTypeDescriptor, nameDescriptor, ageDescriptor];
}
if (!JC_CHECK_NSSTRING(attribute) && !JC_CHECK_NSSTRING(searchName)) {
//查找某個屬性的值包含某個字符串
//%K 屬性的值 %@ 字符串 ==
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"%K CONTAINS[cd] %@", attribute, searchName];
}
NSFetchedResultsController *fetchController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[JCCoreDataManager sharedInstanceManager].objectContext sectionNameKeyPath:nil cacheName:nil];
NSError *error;
if ([fetchController performFetch:&error]){
return [fetchController fetchedObjects];
}else{
NSLog(@"%@", error);
return @[];
}
}
#pragma mark -刪除數(shù)據(jù)
+ (NSString *)deleteWithEntityName:(NSString *)entityName andAttribute:(NSString *)attribute andSearchName:(NSString *)searchName{
//沒有刪除條件
if (JC_CHECK_NSSTRING(attribute) || JC_CHECK_NSSTRING(searchName)) {
return @"沒有刪除條件或條件不完整";
}
//查找
NSArray *arr = [JCCoreDataManager searchCoreDataWithEntityName:entityName andAttribute:attribute andSelectName:searchName sorting:attribute isAsending:YES];
if (arr.count == 0)
return @"沒有找到數(shù)據(jù)";
if (arr.count>0) {
//刪除
for (NSManagedObject *object in arr) {
[[JCCoreDataManager sharedInstanceManager].objectContext deleteObject:object];
}
}
//存儲數(shù)據(jù)
[JCCoreDataManager save];
return @"刪除成功";
}
@end
數(shù)據(jù)處理和創(chuàng)建都只針對JCStudentModel,后面會補(bǔ)充相關(guān)數(shù)據(jù)的創(chuàng)建、關(guān)聯(lián)、查找、刪除。
創(chuàng)建數(shù)據(jù)(10個隨機(jī)數(shù)據(jù)為例)
for (int i = 0; i<10; i++) {
JCStudentModel *studentModel = (JCStudentModel *)[JCCoreDataManager getManagedObjectWithEntityName:NSStringFromClass([JCStudentModel class])];
uint32_t r = arc4random_uniform(99)+1;
studentModel.name = [NSString stringWithFormat:@"student%@", r<10?[NSString stringWithFormat:@"0%u", r]:[NSString stringWithFormat:@"%u", r]];
studentModel.age = arc4random_uniform(8)+10;
studentModel.bloodType = arc4random_uniform(101)>50?@"A":@"B";
}
NSString *ans = [JCCoreDataManager save];
其他都只要調(diào)用一句即可:
//刪除所有數(shù)據(jù)
[JCCoreDataManager deleteCoreData];
//條件查找
NSArray *a = [JCCoreDataManager searchCoreDataWithEntityName:NSStringFromClass([JCStudentModel class]) andAttribute:attribute andSelectName:selectName sorting:sortAttribute isAsending:YES];
//條件刪除
[JCCoreDataManager deleteWithEntityName:NSStringFromClass([JCStudentModel class]) andAttribute:attribute andSearchName:_keyWordsTextField.text];