├── CoreDataTest.xcodeproj ├── project.pbxproj └── project.xcworkspace │ └── contents.xcworkspacedata ├── CoreDataTest ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── CoreDataTest.xcdatamodeld │ ├── .xccurrentversion │ └── CoreDataTest.xcdatamodel │ │ └── contents ├── Info.plist ├── Test+CoreDataProperties.h ├── Test+CoreDataProperties.m ├── Test.h ├── Test.m ├── UserInfoModel.h ├── UserInfoModel.m ├── ViewController.h ├── ViewController.m └── main.m └── README.md /CoreDataTest.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | C49882D91D6EC8940080A44D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = C49882D81D6EC8940080A44D /* main.m */; }; 11 | C49882DC1D6EC8940080A44D /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = C49882DB1D6EC8940080A44D /* AppDelegate.m */; }; 12 | C49882DF1D6EC8940080A44D /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C49882DE1D6EC8940080A44D /* ViewController.m */; }; 13 | C49882E21D6EC8940080A44D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C49882E01D6EC8940080A44D /* Main.storyboard */; }; 14 | C49882E51D6EC8940080A44D /* CoreDataTest.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = C49882E31D6EC8940080A44D /* CoreDataTest.xcdatamodeld */; }; 15 | C49882E71D6EC8940080A44D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C49882E61D6EC8940080A44D /* Assets.xcassets */; }; 16 | C49882EA1D6EC8940080A44D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C49882E81D6EC8940080A44D /* LaunchScreen.storyboard */; }; 17 | C49882F91D6ECA4F0080A44D /* UserInfoModel.m in Sources */ = {isa = PBXBuildFile; fileRef = C49882F81D6ECA4F0080A44D /* UserInfoModel.m */; }; 18 | C49882FE1D6FC8560080A44D /* Test+CoreDataProperties.m in Sources */ = {isa = PBXBuildFile; fileRef = C49882FB1D6FC8560080A44D /* Test+CoreDataProperties.m */; }; 19 | C49882FF1D6FC8560080A44D /* Test.m in Sources */ = {isa = PBXBuildFile; fileRef = C49882FD1D6FC8560080A44D /* Test.m */; }; 20 | /* End PBXBuildFile section */ 21 | 22 | /* Begin PBXFileReference section */ 23 | C49882D41D6EC8940080A44D /* CoreDataTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CoreDataTest.app; sourceTree = BUILT_PRODUCTS_DIR; }; 24 | C49882D81D6EC8940080A44D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 25 | C49882DA1D6EC8940080A44D /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 26 | C49882DB1D6EC8940080A44D /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 27 | C49882DD1D6EC8940080A44D /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 28 | C49882DE1D6EC8940080A44D /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 29 | C49882E11D6EC8940080A44D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 30 | C49882E41D6EC8940080A44D /* CoreDataTest.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = CoreDataTest.xcdatamodel; sourceTree = ""; }; 31 | C49882E61D6EC8940080A44D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 32 | C49882E91D6EC8940080A44D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 33 | C49882EB1D6EC8940080A44D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 34 | C49882F71D6ECA4F0080A44D /* UserInfoModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserInfoModel.h; sourceTree = ""; }; 35 | C49882F81D6ECA4F0080A44D /* UserInfoModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UserInfoModel.m; sourceTree = ""; }; 36 | C49882FA1D6FC8560080A44D /* Test+CoreDataProperties.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Test+CoreDataProperties.h"; sourceTree = ""; }; 37 | C49882FB1D6FC8560080A44D /* Test+CoreDataProperties.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "Test+CoreDataProperties.m"; sourceTree = ""; }; 38 | C49882FC1D6FC8560080A44D /* Test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Test.h; sourceTree = ""; }; 39 | C49882FD1D6FC8560080A44D /* Test.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Test.m; sourceTree = ""; }; 40 | /* End PBXFileReference section */ 41 | 42 | /* Begin PBXFrameworksBuildPhase section */ 43 | C49882D11D6EC8940080A44D /* Frameworks */ = { 44 | isa = PBXFrameworksBuildPhase; 45 | buildActionMask = 2147483647; 46 | files = ( 47 | ); 48 | runOnlyForDeploymentPostprocessing = 0; 49 | }; 50 | /* End PBXFrameworksBuildPhase section */ 51 | 52 | /* Begin PBXGroup section */ 53 | C49882CB1D6EC8940080A44D = { 54 | isa = PBXGroup; 55 | children = ( 56 | C49882D61D6EC8940080A44D /* CoreDataTest */, 57 | C49882D51D6EC8940080A44D /* Products */, 58 | ); 59 | sourceTree = ""; 60 | }; 61 | C49882D51D6EC8940080A44D /* Products */ = { 62 | isa = PBXGroup; 63 | children = ( 64 | C49882D41D6EC8940080A44D /* CoreDataTest.app */, 65 | ); 66 | name = Products; 67 | sourceTree = ""; 68 | }; 69 | C49882D61D6EC8940080A44D /* CoreDataTest */ = { 70 | isa = PBXGroup; 71 | children = ( 72 | C49882DA1D6EC8940080A44D /* AppDelegate.h */, 73 | C49882DB1D6EC8940080A44D /* AppDelegate.m */, 74 | C49882DD1D6EC8940080A44D /* ViewController.h */, 75 | C49882DE1D6EC8940080A44D /* ViewController.m */, 76 | C49882E01D6EC8940080A44D /* Main.storyboard */, 77 | C49882E61D6EC8940080A44D /* Assets.xcassets */, 78 | C49882E81D6EC8940080A44D /* LaunchScreen.storyboard */, 79 | C49882EB1D6EC8940080A44D /* Info.plist */, 80 | C49882E31D6EC8940080A44D /* CoreDataTest.xcdatamodeld */, 81 | C49882FA1D6FC8560080A44D /* Test+CoreDataProperties.h */, 82 | C49882FB1D6FC8560080A44D /* Test+CoreDataProperties.m */, 83 | C49882FC1D6FC8560080A44D /* Test.h */, 84 | C49882FD1D6FC8560080A44D /* Test.m */, 85 | C49882D71D6EC8940080A44D /* Supporting Files */, 86 | C49882F71D6ECA4F0080A44D /* UserInfoModel.h */, 87 | C49882F81D6ECA4F0080A44D /* UserInfoModel.m */, 88 | ); 89 | path = CoreDataTest; 90 | sourceTree = ""; 91 | }; 92 | C49882D71D6EC8940080A44D /* Supporting Files */ = { 93 | isa = PBXGroup; 94 | children = ( 95 | C49882D81D6EC8940080A44D /* main.m */, 96 | ); 97 | name = "Supporting Files"; 98 | sourceTree = ""; 99 | }; 100 | /* End PBXGroup section */ 101 | 102 | /* Begin PBXNativeTarget section */ 103 | C49882D31D6EC8940080A44D /* CoreDataTest */ = { 104 | isa = PBXNativeTarget; 105 | buildConfigurationList = C49882EE1D6EC8940080A44D /* Build configuration list for PBXNativeTarget "CoreDataTest" */; 106 | buildPhases = ( 107 | C49882D01D6EC8940080A44D /* Sources */, 108 | C49882D11D6EC8940080A44D /* Frameworks */, 109 | C49882D21D6EC8940080A44D /* Resources */, 110 | ); 111 | buildRules = ( 112 | ); 113 | dependencies = ( 114 | ); 115 | name = CoreDataTest; 116 | productName = CoreDataTest; 117 | productReference = C49882D41D6EC8940080A44D /* CoreDataTest.app */; 118 | productType = "com.apple.product-type.application"; 119 | }; 120 | /* End PBXNativeTarget section */ 121 | 122 | /* Begin PBXProject section */ 123 | C49882CC1D6EC8940080A44D /* Project object */ = { 124 | isa = PBXProject; 125 | attributes = { 126 | LastUpgradeCheck = 0710; 127 | ORGANIZATIONNAME = "邬志成"; 128 | TargetAttributes = { 129 | C49882D31D6EC8940080A44D = { 130 | CreatedOnToolsVersion = 7.1; 131 | DevelopmentTeam = U4M9ZNVDZ2; 132 | }; 133 | }; 134 | }; 135 | buildConfigurationList = C49882CF1D6EC8940080A44D /* Build configuration list for PBXProject "CoreDataTest" */; 136 | compatibilityVersion = "Xcode 3.2"; 137 | developmentRegion = English; 138 | hasScannedForEncodings = 0; 139 | knownRegions = ( 140 | en, 141 | Base, 142 | ); 143 | mainGroup = C49882CB1D6EC8940080A44D; 144 | productRefGroup = C49882D51D6EC8940080A44D /* Products */; 145 | projectDirPath = ""; 146 | projectRoot = ""; 147 | targets = ( 148 | C49882D31D6EC8940080A44D /* CoreDataTest */, 149 | ); 150 | }; 151 | /* End PBXProject section */ 152 | 153 | /* Begin PBXResourcesBuildPhase section */ 154 | C49882D21D6EC8940080A44D /* Resources */ = { 155 | isa = PBXResourcesBuildPhase; 156 | buildActionMask = 2147483647; 157 | files = ( 158 | C49882EA1D6EC8940080A44D /* LaunchScreen.storyboard in Resources */, 159 | C49882E71D6EC8940080A44D /* Assets.xcassets in Resources */, 160 | C49882E21D6EC8940080A44D /* Main.storyboard in Resources */, 161 | ); 162 | runOnlyForDeploymentPostprocessing = 0; 163 | }; 164 | /* End PBXResourcesBuildPhase section */ 165 | 166 | /* Begin PBXSourcesBuildPhase section */ 167 | C49882D01D6EC8940080A44D /* Sources */ = { 168 | isa = PBXSourcesBuildPhase; 169 | buildActionMask = 2147483647; 170 | files = ( 171 | C49882F91D6ECA4F0080A44D /* UserInfoModel.m in Sources */, 172 | C49882E51D6EC8940080A44D /* CoreDataTest.xcdatamodeld in Sources */, 173 | C49882DF1D6EC8940080A44D /* ViewController.m in Sources */, 174 | C49882DC1D6EC8940080A44D /* AppDelegate.m in Sources */, 175 | C49882FF1D6FC8560080A44D /* Test.m in Sources */, 176 | C49882D91D6EC8940080A44D /* main.m in Sources */, 177 | C49882FE1D6FC8560080A44D /* Test+CoreDataProperties.m in Sources */, 178 | ); 179 | runOnlyForDeploymentPostprocessing = 0; 180 | }; 181 | /* End PBXSourcesBuildPhase section */ 182 | 183 | /* Begin PBXVariantGroup section */ 184 | C49882E01D6EC8940080A44D /* Main.storyboard */ = { 185 | isa = PBXVariantGroup; 186 | children = ( 187 | C49882E11D6EC8940080A44D /* Base */, 188 | ); 189 | name = Main.storyboard; 190 | sourceTree = ""; 191 | }; 192 | C49882E81D6EC8940080A44D /* LaunchScreen.storyboard */ = { 193 | isa = PBXVariantGroup; 194 | children = ( 195 | C49882E91D6EC8940080A44D /* Base */, 196 | ); 197 | name = LaunchScreen.storyboard; 198 | sourceTree = ""; 199 | }; 200 | /* End PBXVariantGroup section */ 201 | 202 | /* Begin XCBuildConfiguration section */ 203 | C49882EC1D6EC8940080A44D /* Debug */ = { 204 | isa = XCBuildConfiguration; 205 | buildSettings = { 206 | ALWAYS_SEARCH_USER_PATHS = NO; 207 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 208 | CLANG_CXX_LIBRARY = "libc++"; 209 | CLANG_ENABLE_MODULES = YES; 210 | CLANG_ENABLE_OBJC_ARC = YES; 211 | CLANG_WARN_BOOL_CONVERSION = YES; 212 | CLANG_WARN_CONSTANT_CONVERSION = YES; 213 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 214 | CLANG_WARN_EMPTY_BODY = YES; 215 | CLANG_WARN_ENUM_CONVERSION = YES; 216 | CLANG_WARN_INT_CONVERSION = YES; 217 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 218 | CLANG_WARN_UNREACHABLE_CODE = YES; 219 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 220 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 221 | COPY_PHASE_STRIP = NO; 222 | DEBUG_INFORMATION_FORMAT = dwarf; 223 | ENABLE_STRICT_OBJC_MSGSEND = YES; 224 | ENABLE_TESTABILITY = YES; 225 | GCC_C_LANGUAGE_STANDARD = gnu99; 226 | GCC_DYNAMIC_NO_PIC = NO; 227 | GCC_NO_COMMON_BLOCKS = YES; 228 | GCC_OPTIMIZATION_LEVEL = 0; 229 | GCC_PREPROCESSOR_DEFINITIONS = ( 230 | "DEBUG=1", 231 | "$(inherited)", 232 | ); 233 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 234 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 235 | GCC_WARN_UNDECLARED_SELECTOR = YES; 236 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 237 | GCC_WARN_UNUSED_FUNCTION = YES; 238 | GCC_WARN_UNUSED_VARIABLE = YES; 239 | IPHONEOS_DEPLOYMENT_TARGET = 9.1; 240 | MTL_ENABLE_DEBUG_INFO = YES; 241 | ONLY_ACTIVE_ARCH = YES; 242 | SDKROOT = iphoneos; 243 | TARGETED_DEVICE_FAMILY = "1,2"; 244 | }; 245 | name = Debug; 246 | }; 247 | C49882ED1D6EC8940080A44D /* Release */ = { 248 | isa = XCBuildConfiguration; 249 | buildSettings = { 250 | ALWAYS_SEARCH_USER_PATHS = NO; 251 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 252 | CLANG_CXX_LIBRARY = "libc++"; 253 | CLANG_ENABLE_MODULES = YES; 254 | CLANG_ENABLE_OBJC_ARC = YES; 255 | CLANG_WARN_BOOL_CONVERSION = YES; 256 | CLANG_WARN_CONSTANT_CONVERSION = YES; 257 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 258 | CLANG_WARN_EMPTY_BODY = YES; 259 | CLANG_WARN_ENUM_CONVERSION = YES; 260 | CLANG_WARN_INT_CONVERSION = YES; 261 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 262 | CLANG_WARN_UNREACHABLE_CODE = YES; 263 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 264 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 265 | COPY_PHASE_STRIP = NO; 266 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 267 | ENABLE_NS_ASSERTIONS = NO; 268 | ENABLE_STRICT_OBJC_MSGSEND = YES; 269 | GCC_C_LANGUAGE_STANDARD = gnu99; 270 | GCC_NO_COMMON_BLOCKS = YES; 271 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 272 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 273 | GCC_WARN_UNDECLARED_SELECTOR = YES; 274 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 275 | GCC_WARN_UNUSED_FUNCTION = YES; 276 | GCC_WARN_UNUSED_VARIABLE = YES; 277 | IPHONEOS_DEPLOYMENT_TARGET = 9.1; 278 | MTL_ENABLE_DEBUG_INFO = NO; 279 | SDKROOT = iphoneos; 280 | TARGETED_DEVICE_FAMILY = "1,2"; 281 | VALIDATE_PRODUCT = YES; 282 | }; 283 | name = Release; 284 | }; 285 | C49882EF1D6EC8940080A44D /* Debug */ = { 286 | isa = XCBuildConfiguration; 287 | buildSettings = { 288 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 289 | INFOPLIST_FILE = CoreDataTest/Info.plist; 290 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 291 | PRODUCT_BUNDLE_IDENTIFIER = zhicheng.wu.CoreDataTest; 292 | PRODUCT_NAME = "$(TARGET_NAME)"; 293 | }; 294 | name = Debug; 295 | }; 296 | C49882F01D6EC8940080A44D /* Release */ = { 297 | isa = XCBuildConfiguration; 298 | buildSettings = { 299 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 300 | INFOPLIST_FILE = CoreDataTest/Info.plist; 301 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 302 | PRODUCT_BUNDLE_IDENTIFIER = zhicheng.wu.CoreDataTest; 303 | PRODUCT_NAME = "$(TARGET_NAME)"; 304 | }; 305 | name = Release; 306 | }; 307 | /* End XCBuildConfiguration section */ 308 | 309 | /* Begin XCConfigurationList section */ 310 | C49882CF1D6EC8940080A44D /* Build configuration list for PBXProject "CoreDataTest" */ = { 311 | isa = XCConfigurationList; 312 | buildConfigurations = ( 313 | C49882EC1D6EC8940080A44D /* Debug */, 314 | C49882ED1D6EC8940080A44D /* Release */, 315 | ); 316 | defaultConfigurationIsVisible = 0; 317 | defaultConfigurationName = Release; 318 | }; 319 | C49882EE1D6EC8940080A44D /* Build configuration list for PBXNativeTarget "CoreDataTest" */ = { 320 | isa = XCConfigurationList; 321 | buildConfigurations = ( 322 | C49882EF1D6EC8940080A44D /* Debug */, 323 | C49882F01D6EC8940080A44D /* Release */, 324 | ); 325 | defaultConfigurationIsVisible = 0; 326 | defaultConfigurationName = Release; 327 | }; 328 | /* End XCConfigurationList section */ 329 | 330 | /* Begin XCVersionGroup section */ 331 | C49882E31D6EC8940080A44D /* CoreDataTest.xcdatamodeld */ = { 332 | isa = XCVersionGroup; 333 | children = ( 334 | C49882E41D6EC8940080A44D /* CoreDataTest.xcdatamodel */, 335 | ); 336 | currentVersion = C49882E41D6EC8940080A44D /* CoreDataTest.xcdatamodel */; 337 | path = CoreDataTest.xcdatamodeld; 338 | sourceTree = ""; 339 | versionGroupType = wrapper.xcdatamodel; 340 | }; 341 | /* End XCVersionGroup section */ 342 | }; 343 | rootObject = C49882CC1D6EC8940080A44D /* Project object */; 344 | } 345 | -------------------------------------------------------------------------------- /CoreDataTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /CoreDataTest/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // CoreDataTest 4 | // 5 | // Created by 邬志成 on 16/8/25. 6 | // Copyright © 2016年 邬志成. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface AppDelegate : UIResponder 13 | 14 | @property (strong, nonatomic) UIWindow *window; 15 | 16 | @property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext; 17 | @property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel; 18 | @property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator; 19 | 20 | - (void)saveContext; 21 | - (NSURL *)applicationDocumentsDirectory; 22 | 23 | 24 | @end 25 | 26 | -------------------------------------------------------------------------------- /CoreDataTest/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // CoreDataTest 4 | // 5 | // Created by 邬志成 on 16/8/25. 6 | // Copyright © 2016年 邬志成. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | - (void)applicationWillResignActive:(UIApplication *)application { 24 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 25 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 26 | } 27 | 28 | - (void)applicationDidEnterBackground:(UIApplication *)application { 29 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 31 | } 32 | 33 | - (void)applicationWillEnterForeground:(UIApplication *)application { 34 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 35 | } 36 | 37 | - (void)applicationDidBecomeActive:(UIApplication *)application { 38 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 39 | } 40 | 41 | - (void)applicationWillTerminate:(UIApplication *)application { 42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 43 | // Saves changes in the application's managed object context before the application terminates. 44 | [self saveContext]; 45 | } 46 | 47 | #pragma mark - Core Data stack 48 | 49 | @synthesize managedObjectContext = _managedObjectContext; 50 | @synthesize managedObjectModel = _managedObjectModel; 51 | @synthesize persistentStoreCoordinator = _persistentStoreCoordinator; 52 | 53 | - (NSURL *)applicationDocumentsDirectory { 54 | // The directory the application uses to store the Core Data store file. This code uses a directory named "zhicheng.wu.CoreDataTest" in the application's documents directory. 55 | return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; 56 | } 57 | 58 | - (NSManagedObjectModel *)managedObjectModel { 59 | // 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. 60 | if (_managedObjectModel != nil) { 61 | return _managedObjectModel; 62 | } 63 | NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"CoreDataTest" withExtension:@"momd"]; 64 | _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]; 65 | return _managedObjectModel; 66 | } 67 | 68 | - (NSPersistentStoreCoordinator *)persistentStoreCoordinator { 69 | // The persistent store coordinator for the application. This implementation creates and returns a coordinator, having added the store for the application to it. 70 | if (_persistentStoreCoordinator != nil) { 71 | return _persistentStoreCoordinator; 72 | } 73 | 74 | // Create the coordinator and store 75 | 76 | _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; 77 | NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"CoreDataTest.sqlite"]; 78 | NSError *error = nil; 79 | NSString *failureReason = @"There was an error creating or loading the application's saved data."; 80 | if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) { 81 | // Report any error we got. 82 | NSMutableDictionary *dict = [NSMutableDictionary dictionary]; 83 | dict[NSLocalizedDescriptionKey] = @"Failed to initialize the application's saved data"; 84 | dict[NSLocalizedFailureReasonErrorKey] = failureReason; 85 | dict[NSUnderlyingErrorKey] = error; 86 | error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:9999 userInfo:dict]; 87 | // Replace this with code to handle the error appropriately. 88 | // 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. 89 | NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 90 | abort(); 91 | } 92 | 93 | return _persistentStoreCoordinator; 94 | } 95 | 96 | 97 | - (NSManagedObjectContext *)managedObjectContext { 98 | // Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.) 99 | if (_managedObjectContext != nil) { 100 | return _managedObjectContext; 101 | } 102 | 103 | NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; 104 | if (!coordinator) { 105 | return nil; 106 | } 107 | _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType]; 108 | [_managedObjectContext setPersistentStoreCoordinator:coordinator]; 109 | return _managedObjectContext; 110 | } 111 | 112 | #pragma mark - Core Data Saving support 113 | 114 | - (void)saveContext { 115 | NSManagedObjectContext *managedObjectContext = self.managedObjectContext; 116 | if (managedObjectContext != nil) { 117 | NSError *error = nil; 118 | if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) { 119 | // Replace this implementation with code to handle the error appropriately. 120 | // 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. 121 | NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 122 | abort(); 123 | } 124 | } 125 | } 126 | 127 | @end 128 | -------------------------------------------------------------------------------- /CoreDataTest/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "ipad", 35 | "size" : "29x29", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "29x29", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "40x40", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "40x40", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "76x76", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "76x76", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /CoreDataTest/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /CoreDataTest/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /CoreDataTest/CoreDataTest.xcdatamodeld/.xccurrentversion: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | _XCCurrentVersionName 6 | CoreDataTest.xcdatamodel 7 | 8 | 9 | -------------------------------------------------------------------------------- /CoreDataTest/CoreDataTest.xcdatamodeld/CoreDataTest.xcdatamodel/contents: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /CoreDataTest/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /CoreDataTest/Test+CoreDataProperties.h: -------------------------------------------------------------------------------- 1 | // 2 | // Test+CoreDataProperties.h 3 | // CoreDataTest 4 | // 5 | // Created by 邬志成 on 16/8/31. 6 | // Copyright © 2016年 邬志成. All rights reserved. 7 | // 8 | // Choose "Create NSManagedObject Subclass…" from the Core Data editor menu 9 | // to delete and recreate this implementation file for your updated model. 10 | // 11 | 12 | #import "Test.h" 13 | #import "UserInfoModel.h" 14 | 15 | NS_ASSUME_NONNULL_BEGIN 16 | #warning 这里只是使用 Xcode 自动生成这个类,并不需要处理 17 | @interface Test (CoreDataProperties) 18 | 19 | @property (nullable, nonatomic, retain) UserInfoModel *userinfo; 20 | @property (nullable, nonatomic, retain) NSString *username; 21 | @property (nullable, nonatomic, retain) NSNumber *score; 22 | 23 | @end 24 | 25 | NS_ASSUME_NONNULL_END 26 | -------------------------------------------------------------------------------- /CoreDataTest/Test+CoreDataProperties.m: -------------------------------------------------------------------------------- 1 | // 2 | // Test+CoreDataProperties.m 3 | // CoreDataTest 4 | // 5 | // Created by 邬志成 on 16/8/31. 6 | // Copyright © 2016年 邬志成. All rights reserved. 7 | // 8 | // Choose "Create NSManagedObject Subclass…" from the Core Data editor menu 9 | // to delete and recreate this implementation file for your updated model. 10 | // 11 | 12 | #import "Test+CoreDataProperties.h" 13 | 14 | @implementation Test (CoreDataProperties) 15 | 16 | @dynamic userinfo; 17 | @dynamic username; 18 | @dynamic score; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /CoreDataTest/Test.h: -------------------------------------------------------------------------------- 1 | // 2 | // Test.h 3 | // CoreDataTest 4 | // 5 | // Created by 邬志成 on 16/8/26. 6 | // Copyright © 2016年 邬志成. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | #warning 这里只是使用 Xcode 自动生成这个类,并不需要处理 15 | #warning 但是数据模型必须遵守并实现 NSCoding 协议 具体实现请移步 UserInfoModel.m 16 | 17 | @interface Test : NSManagedObject 18 | 19 | // Insert code here to declare functionality of your managed object subclass 20 | 21 | @end 22 | 23 | NS_ASSUME_NONNULL_END 24 | 25 | #import "Test+CoreDataProperties.h" 26 | -------------------------------------------------------------------------------- /CoreDataTest/Test.m: -------------------------------------------------------------------------------- 1 | // 2 | // Test.m 3 | // CoreDataTest 4 | // 5 | // Created by 邬志成 on 16/8/26. 6 | // Copyright © 2016年 邬志成. All rights reserved. 7 | // 8 | 9 | #import "Test.h" 10 | 11 | @implementation Test 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /CoreDataTest/UserInfoModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // UserInfoModel.h 3 | // CoreDataTest 4 | // 5 | // Created by 邬志成 on 16/8/25. 6 | // Copyright © 2016年 邬志成. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UserInfoModel : NSObject 12 | 13 | /* brief:年龄 */ 14 | @property (nonatomic,assign) NSInteger age; 15 | 16 | /* brief:性别 */ 17 | @property (nonatomic,assign) BOOL sex; 18 | 19 | /* brief:地址 */ 20 | @property (nonatomic,strong) NSString *address; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /CoreDataTest/UserInfoModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // UserInfoModel.m 3 | // CoreDataTest 4 | // 5 | // Created by 邬志成 on 16/8/25. 6 | // Copyright © 2016年 邬志成. All rights reserved. 7 | // 8 | 9 | #import "UserInfoModel.h" 10 | 11 | @implementation UserInfoModel 12 | 13 | 14 | #pragma mark - NSCoding 协议实现 15 | 16 | - (void)encodeWithCoder:(NSCoder *)aCoder{ 17 | 18 | [aCoder encodeObject:[NSNumber numberWithInteger:self.age] forKey:@"age"]; 19 | [aCoder encodeObject:[NSNumber numberWithBool:self.sex] forKey:@"sex"]; 20 | [aCoder encodeObject:self.address forKey:@"address"]; 21 | 22 | } 23 | - (nullable instancetype)initWithCoder:(NSCoder *)aDecoder{ 24 | 25 | self = [super init]; 26 | 27 | if (self) { 28 | self.age = [[aDecoder decodeObjectForKey:@"age"] integerValue]; 29 | self.sex = [[aDecoder decodeObjectForKey:@"sex"] boolValue]; 30 | self.address = [aDecoder decodeObjectForKey:@"address"]; 31 | } 32 | 33 | return self; 34 | } 35 | 36 | #pragma mark - NSCopying 协议实现 37 | 38 | - (id)copyWithZone:(nullable NSZone *)zone{ 39 | 40 | UserInfoModel *model = [[UserInfoModel allocWithZone:zone]init]; 41 | 42 | model.address = self.address; 43 | 44 | model.sex = self.sex; 45 | 46 | model.age = self.age; 47 | 48 | return model; 49 | } 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /CoreDataTest/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // CoreDataTest 4 | // 5 | // Created by 邬志成 on 16/8/25. 6 | // Copyright © 2016年 邬志成. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /CoreDataTest/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // CoreDataTest 4 | // 5 | // Created by 邬志成 on 16/8/25. 6 | // Copyright © 2016年 邬志成. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "AppDelegate.h" 11 | #import "UserInfoModel.h" 12 | #import 13 | #import "Test+CoreDataProperties.h" 14 | 15 | @interface ViewController () 16 | 17 | /* brief:应用代理 */ 18 | @property (nonatomic,strong) AppDelegate *app_delegate; 19 | 20 | @end 21 | 22 | @implementation ViewController{ 23 | 24 | NSInteger curPage; 25 | 26 | } 27 | 28 | 29 | 30 | - (void)viewDidLoad { 31 | [super viewDidLoad]; 32 | 33 | curPage = 1; 34 | 35 | 36 | UIButton *btn = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 160, 44)]; 37 | [btn setTitle:@"添加数据" forState:UIControlStateNormal]; 38 | [btn setTitleColor:[UIColor blueColor] forState:UIControlStateNormal]; 39 | [btn setTitleColor:[UIColor grayColor] forState:UIControlStateHighlighted]; 40 | [btn addTarget:self action:@selector(addAction) forControlEvents:UIControlEventTouchUpInside]; 41 | btn.center = CGPointMake(self.view.center.x, self.view.center.y - 100); 42 | [self.view addSubview:btn]; 43 | 44 | UIButton *delBtn = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 160, 44)]; 45 | [delBtn setTitle:@" 删除数据" forState:UIControlStateNormal]; 46 | [delBtn setTitleColor:[UIColor blueColor] forState:UIControlStateNormal]; 47 | [delBtn setTitleColor:[UIColor grayColor] forState:UIControlStateHighlighted]; 48 | [delBtn addTarget:self action:@selector(deleteAction) forControlEvents:UIControlEventTouchUpInside]; 49 | delBtn.center = CGPointMake(self.view.center.x, self.view.center.y - 50); 50 | [self.view addSubview:delBtn]; 51 | 52 | UIButton *resetPageBtn = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 160, 44)]; 53 | [resetPageBtn setTitle:@" 重置页码" forState:UIControlStateNormal]; 54 | [resetPageBtn setTitleColor:[UIColor blueColor] forState:UIControlStateNormal]; 55 | [resetPageBtn setTitleColor:[UIColor grayColor] forState:UIControlStateHighlighted]; 56 | [resetPageBtn addTarget:self action:@selector(resetPageAction) forControlEvents:UIControlEventTouchUpInside]; 57 | resetPageBtn.center = CGPointMake(self.view.center.x, self.view.center.y); 58 | [self.view addSubview:resetPageBtn]; 59 | 60 | 61 | UIButton *changeBtn = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 160, 44)]; 62 | [changeBtn setTitle:@" 修改数据" forState:UIControlStateNormal]; 63 | [changeBtn setTitleColor:[UIColor blueColor] forState:UIControlStateNormal]; 64 | [changeBtn setTitleColor:[UIColor grayColor] forState:UIControlStateHighlighted]; 65 | [changeBtn addTarget:self action:@selector(changeAction) forControlEvents:UIControlEventTouchUpInside]; 66 | changeBtn.center = CGPointMake(self.view.center.x, self.view.center.y + 50); 67 | [self.view addSubview:changeBtn]; 68 | 69 | UIButton *getBtn = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 160, 44)]; 70 | [getBtn setTitle:@"获取数据" forState:UIControlStateNormal]; 71 | [getBtn setTitleColor:[UIColor blueColor] forState:UIControlStateNormal]; 72 | [getBtn setTitleColor:[UIColor grayColor] forState:UIControlStateHighlighted]; 73 | [getBtn addTarget:self action:@selector(getAction) forControlEvents:UIControlEventTouchUpInside]; 74 | getBtn.center = CGPointMake(self.view.center.x, self.view.center.y + 100); 75 | [self.view addSubview:getBtn]; 76 | } 77 | 78 | 79 | /* 增 */ 80 | - (void)addAction { 81 | 82 | Test *obj = [NSEntityDescription insertNewObjectForEntityForName:@"Test" inManagedObjectContext:self.app_delegate.managedObjectContext]; 83 | UserInfoModel *model = [[UserInfoModel alloc]init];{ 84 | model.age = arc4random_uniform(100); 85 | model.sex = arc4random_uniform(2); 86 | model.address = @"江苏省南京市江宁区将军大道十字路口"; 87 | } 88 | 89 | obj.score = @(arc4random_uniform(100)); 90 | obj.username = @"将军大道"; 91 | obj.userinfo = model; 92 | 93 | [self.app_delegate saveContext]; //! < 持久化到本地 94 | 95 | } 96 | 97 | /* 删 */ 98 | - (void)deleteAction{ 99 | 100 | NSFetchRequest *req = [[NSFetchRequest alloc]initWithEntityName:@"Test"]; 101 | 102 | NSArray *objs = [self.app_delegate.managedObjectContext executeFetchRequest:req error:nil]; 103 | 104 | if (objs.count == 0) { 105 | NSLog(@"删除失败 --> 无数据"); 106 | return; 107 | } 108 | 109 | Test *obj = [objs objectAtIndex:arc4random_uniform((u_int32_t)objs.count)]; 110 | 111 | [self.app_delegate.managedObjectContext deleteObject:obj]; //! < 删除对象 112 | 113 | NSLog(@"删除成功"); 114 | 115 | [self.app_delegate saveContext]; //! < 持久化到本地 116 | 117 | 118 | } 119 | 120 | /* 改 */ 121 | - (void)changeAction{ 122 | 123 | NSFetchRequest *req = [[NSFetchRequest alloc]initWithEntityName:@"Test"]; 124 | 125 | NSArray *objs = [self.app_delegate.managedObjectContext executeFetchRequest:req error:nil]; 126 | 127 | if (objs.count == 0) { 128 | NSLog(@"修改失败 ---> 无数据"); 129 | return; 130 | } 131 | 132 | Test *obj = [objs objectAtIndex:arc4random_uniform((u_int32_t)objs.count)]; 133 | 134 | obj.username = @"修改数据"; //! < 拿到数据对象后直接赋值操作并保存即可 135 | UserInfoModel *mod = [obj.userinfo copy]; 136 | mod.address = @"南京市鼓楼区鼓楼地铁站🚇"; 137 | obj.userinfo = mod; 138 | NSLog(@"修改成功"); 139 | 140 | [self.app_delegate saveContext]; //! < 持久化到本地 141 | 142 | 143 | } 144 | 145 | 146 | /* 查 */ 147 | - (void)getAction{ 148 | #warning 对于模型中的数据, NSFetchRequest 并不能对模型中属性值实现过滤操作,但是可以对模型外的数据进行处理 149 | NSFetchRequest *req = [NSFetchRequest fetchRequestWithEntityName:@"Test"]; 150 | 151 | NSSortDescriptor *desc = [NSSortDescriptor sortDescriptorWithKey:@"score" ascending:NO]; //! < 实现查找的数据降序排列(NO,YES 为升序) 152 | 153 | 154 | NSPredicate *predicate = [NSPredicate predicateWithFormat:@"score < %ld", 60]; //! < 将分数小于60的查找出来 155 | 156 | req.predicate = predicate; 157 | 158 | /* 159 | 160 | // 分页用到 查找的数量与偏移量 161 | req.fetchLimit = 5; //! < 数量 | 结论:无论查找的数量设置多少,NSFetchRequest 162 | // | ---> 都会遍历所有数据,并且按照事先约定的条件进行 163 | req.fetchOffset = req.fetchLimit * (curPage - 1); //! < 偏移量 | 处理后输出 164 | 165 | 166 | NSLog(@"**********************第%ld页*************************",curPage); 167 | 168 | */ 169 | req.sortDescriptors = @[desc]; 170 | 171 | NSArray *array = [self.app_delegate.managedObjectContext executeFetchRequest:req error:nil]; 172 | 173 | #pragma 模型内的数据可以采用数组的条件过滤操作,然而当进行此步骤操作时,分页效果将完全乱了 174 | 175 | NSPredicate *array_predicate = [NSPredicate predicateWithFormat:@"userinfo.age < %ld",20]; 176 | 177 | array = [array filteredArrayUsingPredicate:array_predicate]; 178 | 179 | if (array.count == 0) { 180 | NSLog(@"**********************无数据*************************"); 181 | return; 182 | } 183 | 184 | 185 | curPage ++; 186 | 187 | for (Test *obj in array) { 188 | UserInfoModel *model = obj.userinfo; 189 | NSLog(@"%@ | %02ld | %02ld | %@ | %@",obj.username,model.age,[obj.score integerValue],model.sex?@"男":@"女",model.address); 190 | } 191 | 192 | } 193 | 194 | 195 | /* 重置页码 */ 196 | - (void)resetPageAction{ 197 | 198 | curPage = 1; 199 | 200 | } 201 | 202 | 203 | - (AppDelegate *)app_delegate{ 204 | 205 | if (_app_delegate) { 206 | return _app_delegate; 207 | } 208 | 209 | _app_delegate = (AppDelegate *)[UIApplication sharedApplication].delegate; 210 | 211 | return _app_delegate; 212 | } 213 | @end 214 | -------------------------------------------------------------------------------- /CoreDataTest/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // CoreDataTest 4 | // 5 | // Created by 邬志成 on 16/8/25. 6 | // Copyright © 2016年 邬志成. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### Core data 数据库入门及提升 2 | 3 | 如果对你有帮助或者你很喜欢的话请star,感谢支持 4 | 5 | ---- 6 | 这里主要是讲如何使用系统自带的 CoreData 类对数据持久化到本地的操作,对于初学者十分适合使用,作为作者的我,将所有必要的注释全部写的清楚明了,使得 ios 开发人员在参考此文档时既有 demo 又有解释,实现快速上手. 7 | 8 | ---- 9 | 10 | 11 | 12 | - 插入数据/增加数据 13 | 14 | ````objc 15 | 16 | /* 增 */ 17 | - (void)addAction { 18 | 19 | Test *obj = [NSEntityDescription insertNewObjectForEntityForName:@"Test" inManagedObjectContext:self.app_delegate.managedObjectContext]; 20 | UserInfoModel *model = [[UserInfoModel alloc]init];{ 21 | model.age = arc4random_uniform(100); 22 | model.sex = arc4random_uniform(2); 23 | model.address = @"江苏省南京市江宁区将军大道十字路口"; 24 | } 25 | 26 | obj.score = @(arc4random_uniform(100)); 27 | obj.username = @"将军大道"; 28 | obj.userinfo = model; 29 | 30 | [self.app_delegate saveContext]; //! < 持久化到本地 31 | 32 | } 33 | ```` 34 | 35 | - 删除数据 36 | 37 | ````objc 38 | /* 删 */ 39 | - (void)deleteAction{ 40 | 41 | NSFetchRequest *req = [[NSFetchRequest alloc]initWithEntityName:@"Test"]; 42 | 43 | NSArray *objs = [self.app_delegate.managedObjectContext executeFetchRequest:req error:nil]; 44 | 45 | if (objs.count == 0) { 46 | NSLog(@"删除失败 --> 无数据"); 47 | return; 48 | } 49 | 50 | Test *obj = [objs objectAtIndex:arc4random_uniform((u_int32_t)objs.count)]; 51 | 52 | [self.app_delegate.managedObjectContext deleteObject:obj]; //! < 删除对象 53 | 54 | NSLog(@"删除成功"); 55 | 56 | [self.app_delegate saveContext]; //! < 持久化到本地 57 | 58 | 59 | } 60 | 61 | ```` 62 | 63 | - 修改数据 64 | 65 | ````objc 66 | /* 改 */ 67 | - (void)changeAction{ 68 | 69 | NSFetchRequest *req = [[NSFetchRequest alloc]initWithEntityName:@"Test"]; 70 | 71 | NSArray *objs = [self.app_delegate.managedObjectContext executeFetchRequest:req error:nil]; 72 | 73 | if (objs.count == 0) { 74 | NSLog(@"修改失败 ---> 无数据"); 75 | return; 76 | } 77 | 78 | Test *obj = [objs objectAtIndex:arc4random_uniform((u_int32_t)objs.count)]; 79 | 80 | obj.username = @"修改数据"; //! < 拿到数据对象后直接赋值操作并保存即可 81 | UserInfoModel *mod = [obj.userinfo copy]; 82 | mod.address = @"南京市鼓楼区鼓楼地铁站🚇"; 83 | obj.userinfo = mod; 84 | NSLog(@"修改成功"); 85 | 86 | [self.app_delegate saveContext]; //! < 持久化到本地 87 | 88 | 89 | } 90 | ```` 91 | - 查找数据(可以条件查找) 92 | 93 | ````objc 94 | /* 查 */ 95 | - (void)getAction{ 96 | #warning 对于模型中的数据, NSFetchRequest 并不能对模型中属性值实现过滤操作,但是可以对模型外的数据进行处理 97 | NSFetchRequest *req = [NSFetchRequest fetchRequestWithEntityName:@"Test"]; 98 | 99 | NSSortDescriptor *desc = [NSSortDescriptor sortDescriptorWithKey:@"score" ascending:NO]; //! < 实现查找的数据降序排列(NO,YES 为升序) 100 | 101 | 102 | NSPredicate *predicate = [NSPredicate predicateWithFormat:@"score < %ld", 60]; //! < 将分数小于60的查找出来 103 | 104 | req.predicate = predicate; 105 | 106 | /* 107 | 108 | // 分页用到 查找的数量与偏移量 109 | req.fetchLimit = 5; //! < 数量 | 结论:无论查找的数量设置多少,NSFetchRequest 110 | // | ---> 都会遍历所有数据,并且按照事先约定的条件进行 111 | req.fetchOffset = req.fetchLimit * (curPage - 1); //! < 偏移量 | 处理后输出 112 | 113 | 114 | NSLog(@"**********************第%ld页*************************",curPage); 115 | 116 | */ 117 | req.sortDescriptors = @[desc]; 118 | 119 | NSArray *array = [self.app_delegate.managedObjectContext executeFetchRequest:req error:nil]; 120 | 121 | #pragma 模型内的数据可以采用数组的条件过滤操作,然而当进行此步骤操作时,分页效果将完全乱了 122 | 123 | NSPredicate *array_predicate = [NSPredicate predicateWithFormat:@"userinfo.age < %ld",20]; 124 | 125 | array = [array filteredArrayUsingPredicate:array_predicate]; 126 | 127 | if (array.count == 0) { 128 | NSLog(@"**********************无数据*************************"); 129 | return; 130 | } 131 | 132 | 133 | curPage ++; 134 | 135 | for (Test *obj in array) { 136 | UserInfoModel *model = obj.userinfo; 137 | NSLog(@"%@ | %02ld | %02ld | %@ | %@",obj.username,model.age,[obj.score integerValue],model.sex?@"男":@"女",model.address); 138 | } 139 | 140 | } 141 | 142 | ```` 143 | 144 | ---- 145 | 146 | ### 数据持久的变量初始化 147 | - NSManagedObjectContext 初始化 148 | 149 | ````objc 150 | if (_managedObjectContext != nil) { 151 | return _managedObjectContext; 152 | } 153 | 154 | NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; 155 | if (!coordinator) { 156 | return nil; 157 | } 158 | _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType]; 159 | [_managedObjectContext setPersistentStoreCoordinator:coordinator]; //这里需要指定协作器,就是连接对象上下文和模型的桥梁 160 | return _managedObjectContext; 161 | 162 | ```` 163 | 164 | - NSManagedObjectModel 初始化 165 | 166 | ````objc 167 | if (_managedObjectModel != nil) { 168 | return _managedObjectModel; 169 | } 170 | NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"文件名" withExtension:@"momd"]; //这里的`文件名`就是在资源文件中生成的`***.xcdatamodeld `文件名,后缀在 url 中必须为 momd,(其实是个文件夹里面的文件,可以输出地址查看) 171 | _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]; //指定模型地址 172 | return _managedObjectModel; 173 | 174 | ```` 175 | - NSPersistentStoreCoordinator 初始化 176 | 177 | ````objc 178 | if (_persistentStoreCoordinator != nil) { 179 | return _persistentStoreCoordinator; 180 | } 181 | _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; 182 | NSURL *applicationDocumentsDirectory = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; 183 | NSURL *storeURL = [applicationDocumentsDirectory URLByAppendingPathComponent:@"文件名.sqlite"]; //这里是指定数据库存储的地方和名字-->文件名 184 | [_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:nil]; //添加数据库的路径 185 | return _persistentStoreCoordinator; 186 | 187 | ```` 188 | 189 | ### (必须)如果使用了动态存储,则模型需要遵守/实现 NSCoding 协议 190 | 191 | - 例如(实现部分) 192 | ````objc 193 | 194 | - (void)encodeWithCoder:(NSCoder *)aCoder{ 195 | 196 | [aCoder encodeObject:[NSNumber numberWithInteger:self.age] forKey:@"age"]; 197 | [aCoder encodeObject:[NSNumber numberWithBool:self.sex] forKey:@"sex"]; 198 | [aCoder encodeObject:self.address forKey:@"address"]; 199 | 200 | } 201 | - (nullable instancetype)initWithCoder:(NSCoder *)aDecoder{ 202 | 203 | self = [super init]; 204 | 205 | if (self) { 206 | self.age = [[aDecoder decodeObjectForKey:@"age"] integerValue]; 207 | self.sex = [[aDecoder decodeObjectForKey:@"sex"] boolValue]; 208 | self.address = [aDecoder decodeObjectForKey:@"address"]; 209 | } 210 | 211 | return self; 212 | } 213 | 214 | ```` 215 | 216 | ### (可选)如果想通过 copy 来完整拷贝一个模型数据到一个新的模型,则模型需要遵守/实现 NSCopying 协议 217 | 218 | - 例如(实现部分) 219 | ````objc 220 | - (id)copyWithZone:(nullable NSZone *)zone{ 221 | 222 | UserInfoModel *model = [[UserInfoModel allocWithZone:zone]init]; 223 | 224 | model.address = self.address; 225 | 226 | model.sex = self.sex; 227 | 228 | model.age = self.age; 229 | 230 | return model; 231 | } 232 | 233 | ```` 234 | --------------------------------------------------------------------------------