Introduction to storage mode

  1. NSKeyedArchiver: Archive data in a sandbox;
  2. NSUserDefaults: Save Preferences data in the Library/Preferences directory of the sandbox (essentially plist);
  3. Write: permanently stored on disk;
  4. Use SQLite and other databases to store data.

1. NSKYEDARCHIVER :(Archiving)

The data object must comply with the NSCODING protocol, and the corresponding class must provide the encodeWithCoder: and initWithCoder: methods. The first method tells the system how to encode the object, while the second method tells the system how to decode the object.


Archive the form to save the data, can only be archived and decompressed once. Therefore, only a small amount of data can be targeted, and the data operation is relatively clumsy, that is, if you want to change a small part of the data, you still need to decompress the whole data or archive the whole data.

Note: When does initWithCoder call [super initWithCoder:]?
• InitWithCoder Principle: Whenever you parse a file, you call it. The XIB and the storyboard are both files, so whenever you parse these two files, you call initWithCoder. • So if you use a custom view in a storyboard and override the initWithCoder method, make sure you call [super initWithCoder:], because only the system knows how to parse the storyboard, and if you don't call it, you can't parse the file.

2.NSUserDefaults :(Preferences, essentially PLIST)

Used to store application Settings and properties, user-saved data. The data still exists after the user opens the program again or starts the computer. The data types that NSUserDefaults can store include: NSData, NSString, NSNumber, NSDate, NSArray, and NSDictionary. If you want to store another type, you have to convert it to the previous type in order to store it in NSUserDefaults.

  • Advantage: 1. Do not need to care about the file name 2. Do key-value pair storage quickly
  • Cons: can be stored in time, need to do synchronization operation, the memory of the data synchronization to the hard disk
  • Bottom layer: encapsulates a dictionary

    • Sandbox structure analysis:
    • Application package: Contains all resource files and executables.
    • Documents: Save persistent data that was created while the application was running and is backed up when iTunes syncs the device. (For example, a game application can save games to the directory where they are saved. Large data cannot be stored here, once stored, IOS audit will not pass)
    • TMP: Save the temporary data needed by the application while it is running, and then delete the corresponding files from the directory after use. When the application is not running, the system may also clear the files in this directory. This directory is not backed up when iTunes syncs the device.
    • Library/Caches: Holds persistent data generated while the application is running. It is not backed up when the device is synced with iTunes. General storage volume, do not need backup of non-important data. (Generally put the cached downloaded files here)
    • Library/Preference: Store all of your app’s preferences. The iOS Settings app looks in this directory for your app’s Settings. The iTunes syncing device backs up the directory.
Note: Prior to iOS7, the default is not to synchronize with the disk immediately. You can call [userDefaults synchronize]. Synchronous operation

3. Write: Always save to disk.

4. Use a database to store data.

4.1 the SQLite

SQLite ( is a lightweight relational database. The iOS SDK has long supported SQLite. To use it, you just need to add the libsqlite3.dylib dependency and the sqlite3.h header file. However, the native SQLite API is quite unfriendly to use and very inconvenient to use.

4.2 FMDB
  • FMDB is a SQLite database framework for iOS platform. FMDB encapsulates SQLite’s C language API in the form of OC
  • The advantages of FMDB are more object-oriented, save a lot of trouble, the redundant C language code compared with Apple’s own Core Data framework, more lightweight and flexible to provide a multi-thread safe database operation method, effectively prevent Data chaos
  • FMDB has three main classes
  1. FMDatabase An FMDatabase object represents a single SQLite database used to execute SQL statements
  2. The FMResultSet uses the FMDatabase to execute the result set of the query
  3. FMDatabaseQueue is used to perform multiple queries or updates in multiple threads and is thread-safe

The FMDatabase object is created by specifying the path to the SQLite database file

/ / get the database file path nsstrings * doc = [NSSearchPathForDirectoriesInDomains (NSDocumentDirectory NSUserDomainMask, YES) lastObject]; NSString *fileName=[doc stringByAppendingPathComponent:@"user.sqlite"]; FMDatabase *db = [FMDatabase databaseWithPath:path]; if (! [db open]) {NSLog(@" database open failed!" ); }

In FMDB, all operations other than queries are referred to as “updates”, such as CREATE, DROP, INSERT, UPDATE, DELETE, and so on

Execute the update with the executeUpdate: method - (BOOL)executeUpdate:(NSString*) SQL,... - (BOOL)executeUpdateWithFormat:(NSString*)format, ... - (BOOL) ExecuteUpdate :(NSString*) SQL withArgumentsinArray :(NSArray *)arguments // Example [db ExecuteUpdate :@"UPDATE t_user SET age = ? WHERE name = ?;", @20, @"Jack"]

Execute the query

Query Method - (FMResultSet *) ExecuteQuery :(NSString*) SQL,... - (FMResultSet *)executeQueryWithFormat:(NSString*)format, ... - (FMResultSet *) ExecuteQuery :(NSString *) SQL withArgumentSinArray :(NSArray *)arguments  executeQuery:@"SELECT * FROM t_user"]; // while ([rs next]) {nsString *name = [rs StringForColumn :@"name"]; int age = [rs intForColumn:@"age"]; NSString *sex = [rs doubleForColumn:@"sex"]; }

Use FMDatabaseQueue thread-safe: It is unwise to use a single FMDatabase instance in multiple threads. Now you can create an FMDatabase object per thread. Do not have multiple threads share the same instance; it cannot be used in multiple threads at the same time. If so, the program will crash from time to time, or report an exception, causing people to crash. So, don’t initialize an FMDatabase object and use it across multiple threads.

Use FMDatabaseQueue. Here’s how to use it:

// First create the queue. FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:aPath]; // Use it this way. [queue inDatabase:^(FMDatabase *db) { [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:1]]; [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:2]]; [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [nsNumber numberWithInt:3]]; fmResultSet *rs = [db executeQuery:@"select * from foo"]; while([rs next]) {...}}]; // Easily wrap a simple task into a transaction like this:  [queue inTransaction:^(FMDatabase *db, BOOL *rollback) { [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:1]]; [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:2]]; [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt: 3]]; the if (whoopsSomethingWrongHappened) {* rollback = YES; return;} / / etc... [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:4]]; }];

The FMDatabaseQueue background creates a serialized G-C-D queue and executes the blocks you pass to the G-C-D queue. This means that when you call methods from multiple threads at the same time, GDC will execute them in the order in which it receives blocks.

4.3 Realm

In the mobile field, SQLite database has been occupying an unshakable position. The creators of SQLite followed a small but refined philosophy, implementing the core logic of a relational database with a tiny amount of C code. However, when relational databases encounter object-oriented programming languages, a difficult problem arises for programmers. In order to convert relational data to objects, we need to use SQL statements to query the corresponding values. Then, we assign a value to the object. This duplication of work caused some trouble in coding, and in order to solve this problem, ORM framework was developed

ORM (Object Relational Mapping)

ORM frameworks prevent you from using SQL statements directly for queries. Instead, use object-oriented approach to help you complete the query of data, and automatically map to the corresponding object. This can be a lifesaver for programmers who are fed up with tedious SQL statements. Realm is still an ORM solution for relational databases, and the amazing thing is that Realm is almost always faster than SQLite or close to SQLite in terms of adding, deleting, updating, and searching. How could a Realm have such amazing speed with the same ORM framework?

The answer is that Realm’s underlying implementation is largely in C++, with native support for object-oriented queries. It took a lot of optimization to achieve the same performance as SQLite.

Performance concerns aside, I started looking at the official documentation, which was very detailed and even available in Chinese.

For the mobile terminal database, the following aspects have to be considered: 1) the upgrade of the database version; 2) whether the external debugging tools are perfect; 3) whether the complex query is supported

The Realm documentation contains detailed answers to these three questions, but let me briefly address them. The first question is that Realm provides the Migration class to upgrade and maintain the Realm database version. Second, Realm provides a Mac version of the Realm Browser for easy debugging on Mac machines. Unfortunately, however, a Windows version, LOL, is not available. Third, Realm has chapters devoted to multi-table query methods and one-to-many, many-to-many table solutions.

4.4 CoreData

  • What is CoreData?

    • Core Data is a framework that has been around since iOS5. It provides object-relational mapping (ORM), which is the ability to convert OC objects to Data stored in SQLite database files and restore Data stored in the database to OC objects. We do not need to write any SQL statements during this data manipulation
    • CoreData cannot execute SQL statements and instead operates on objects. The popular tripartite library, FMDB SQLite, allows direct SQL statements
  • What’s the difference between CoreData and a database?

    • CoreData is an Apple-native framework that has the ability to store data like a database, but is not itself a database

      • Core Data is a powerful framework in the iOS SDK that allows programmers to store and manage Data in an object-oriented manner. With the CoreData framework, programmers can easily and efficiently manage Data through an object-oriented interface, so CoreData is not a database. Don’t look at it like a database.
    • Core Data is not an application database, nor is it an API for persistently saving Data to a database. Core Data is a framework for managing object graphs. Core Data can write object graphs to disk for persistence
  • What are the features of Coredata?

    • (1)CoreData provides model-level technology for data persistence directly on OC objects

      • Core Data is a model-level technology. To help build a model layer that represents the state of an application, Core Data is also a persistence technology. It can persist the state of a model object to disk, but its most important feature is that Core Data is not only a framework for loading and storing Data, it also works well with Data in memory
    • (2) During the data storage operation, CoreData does not need to write any SQL statements
    • (3) Core Data usage includes entities and relationships between entities, as well as finding requests for entities that meet certain criteria
    • (4) Developers can find and manage this data at the pure object level without worrying about the implementation details of storage and lookup
    • (5) The Core Data framework first appeared on Mac OS X 10.4 Tiger and iOS 3.0, and has been tested by thousands of applications and millions of users. It is a very mature framework
    • (6) CoreData leverages the Objective-C language and runtime to integrate nicely with the Core Foundation framework. Is an easy to use framework that not only gracefully manages object graphs, but also performs exceptionally well in memory management

CoreData principle:

  • At first glance at Core Data’s daunting and complex architectural relationships, many people have a feeling of bewilderment
  • However, once you understand the components of the architecture diagram and how they relate to each other, you can appreciate the simplicity and intuition of the Core Data API
  • Core Data Stack (Technology Stack) : If you understand the roles of the individual members of the Core Data Stack, then using Core Data should not be difficult

1.1- What is the CoreData Stack?

  • The Core Data Stack is the Core of Core Data and consists of a set of Core Data Core objects

    • NS-managed ObjectContext object management context: The collection of objects responsible for managing the model
    • NS-managed object model: Responsible for managing the object model
    • NSPersistentStoreCoordinator storage scheduler: responsible for the data is saved to disk

1.2- How do the objects in the CoreData Stack work together?

  • The composition can be divided into two parts

    • Object graph management: mainly refers to the object management context (NS-managed object context) through the object model (NS-managed object model) implementation of object management.
    • Data persistence: mainly refers to the storage (NSPersistentStore) to operate the SQLite database, the data stored in the disk (this part is the system to do for us do not need us to care).

      • In the middle of these two parts, in the middle of the stack, is the Persistent Store Coordinator (PSC). It ties together the image management part and the persistence part. When one of these two components needs to interact with the other, it is mediated by the PSC
  • Points to note:
  • A project can have multiple context-management models, and a storage scheduler can schedule multiple stores, but in normal development, we only need one Contect and one store