xcode iOS:如何保存在应用程序中创建的自定义对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7296107/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 21:52:03  来源:igfitidea点击:

iOS: How to save a custom object that is created in an app

objective-ciosxcodecore-dataplist

提问by 5StringRyan

I've been reading up on saving objects, preserving state etc, but I'm still a little confused on the route I should take when saving objects that are created from my app. I have built an app where a user can create a Radio Station with the Genre, name and frequency. Once a user hits save, a "RadioStation" object is created using a custom class and is stored in an NSMutableArray that is placed in the RootViewController. While RadioStation objects can be stored in this array and are displayed correctly in the table view, it's obvious that once the application quits, these are no longer going to be held by the application.

我一直在阅读有关保存对象、保留状态等方面的内容,但我仍然对保存从我的应用程序创建的对象时应该采取的路线感到有些困惑。我构建了一个应用程序,用户可以在其中创建具有流派、名称和频率的广播电台。一旦用户点击保存,就会使用自定义类创建一个“RadioStation”对象,并将其存储在放置在 RootViewController 中的 NSMutableArray 中。虽然 RadioStation 对象可以存储在这个数组中并在表视图中正确显示,但很明显,一旦应用程序退出,应用程序将不再持有这些对象。

At this point I'm not sure how I should begin to architect this design. Do I need to set up a plist? Should I use Core Data with a SQLite DB? Do I need to research iOS object serialization for both these scenarios? Or is there an more straight forward way that I'm not aware of?

在这一点上,我不确定我应该如何开始构建这个设计。我需要设置一个 plist 吗?我应该将 Core Data 与 SQLite DB 一起使用吗?我是否需要针对这两种情况研究 iOS 对象序列化?或者有没有我不知道的更直接的方法?

回答by AndrewS

There are three ways to persist data locally:

本地持久化数据的三种方式:

  1. Store objects in a database using managed objects or SQLite
  2. Store objects in a file in the sandbox using various classes' writeToFile
  3. Store the data in NSUserDefaults
  1. 使用托管对象或 SQLite 在数据库中存储对象
  2. 使用各种类的 writeToFile 将对象存储在沙箱中的文件中
  3. 将数据存储在 NSUserDefaults 中

How you persist your object data depends on how you're using it, and what type of data you're saving. CoreData makes sense if you have a lot of objects of the same type and SQL's search and sorting mechanisms would be useful. I tend to use the sandbox for very large files, eg images, sound files, and large agglomerations of data bounced through NSData. And I use UserDefaults for small amounts of data that might be considered "preferences".

您如何持久保存对象数据取决于您如何使用它以及您保存的数据类型。如果您有很多相同类型的对象,并且 SQL 的搜索和排序机制会很有用,那么 CoreData 是有意义的。我倾向于将沙箱用于非常大的文件,例如图像、声音文件和通过 NSData 反弹的大量数据。我将 UserDefaults 用于可能被视为“首选项”的少量数据。

You can put anything anywhere you want, and I suggest being familiar with all three mechanisms when you start a new project. Additional techniques, like using NSCoding to serialize and deserialize classes, can be used to make saving data easier. Note that once you've implemented NSCoding, you could store data anywhere and even send it over the wire.

你可以把任何东西放在任何你想要的地方,我建议你在开始一个新项目时熟悉这三种机制。其他技术,例如使用 NSCoding 来序列化和反序列化类,可用于更轻松地保存数据。请注意,一旦您实现了 NSCoding,您就可以将数据存储在任何地方,甚至可以通过网络发送。

For your RadioStation, I would personally use UserDefaults. The benefit of using NSCoding is that, once you implement initWithCoder and encodeWithCoder, you can stream a hierarchy of objects (eg an array of custom objects, each of which might contain a dictionary, array, or custom object, etc) fairly easily. If the only thing you're saving is an array of strings, then directly using UserDefaults is easy enough.

对于您的 RadioStation,我个人会使用 UserDefaults。使用 NSCoding 的好处是,一旦你实现了 initWithCoder 和 encodeWithCoder,你就可以很容易地流式传输对象的层次结构(例如自定义对象数组,每个对象可能包含字典、数组或自定义对象等)。如果您保存的唯一内容是字符串数组,那么直接使用 UserDefaults 就足够简单了。

回答by Abhi Beckert

The most powerful approach is to make your custom object a subclass of NSManagedObject, and store it in an NSManagedObjectContextusing Core Data. On iOS this will always use an sqlite database, on Mac OS X you can use sqlite, xml, or a proprietary binary format (smaller/faster than xml).

最强大的方法是使您的自定义对象成为 的子类NSManagedObject,并将其存储在NSManagedObjectContextusing Core Data 中。在 iOS 上,这将始终使用 sqlite 数据库,在 Mac OS X 上,您可以使用 sqlite、xml 或专有二进制格式(比 xml 更小/更快)。

Depending on how complicated your data structure is, and how likely it is to change in future, this technique may or may not be too complicated for your app. It's a lot of work to setup, and the API is very complicated, but it's the best choice if you need to store tens of thousands/millions of objects in a file.

根据您的数据结构的复杂程度以及未来更改的可能性,此技术对您的应用程序来说可能太复杂,也可能不太复杂。设置工作量很大,API也很复杂,但是如果你需要在一个文件中存储数万/数百万个对象,它是最好的选择。

For your app, I would have a single sqlite file containing all of the radio stations in the app.

对于您的应用程序,我将有一个包含应用程序中所有广播电台的 sqlite 文件。



The simplest option, is to implement the NSCodingprotocol in your custom object's class. Documented here:

最简单的选择是NSCoding在自定义对象的类中实现协议。记录在这里:

http://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Archiving/Articles/codingobjects.html#//apple_ref/doc/uid/20000948-BCIHBJDE

http://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Archiving/Articles/codingobjects.html#//apple_ref/doc/uid/20000948-BCIHBJDE

The basic theory is your object writes or reads all it's data to a "coder", and then passes the coder on to any child object(s). Outside of the class, you use an "archiver" or an "unarchiver" class to coordinate everything.

基本理论是您的对象将其所有数据写入或读取到“编码器”,然后将编码器传递给任何子对象。在课程之外,您可以使用“归档程序”或“取消归档程序”类来协调所有内容。

Once your custom class implements NSCodingyou can read/write it to the disk with:

实现自定义类后,NSCoding您可以使用以下命令将其读/写到磁盘:

myObject = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
[NSKeyedArchiver archiveRootObject:myObject toFile:filePath];

This is a very simple approach, but it has a few drawbacks, for example you will need to figure out your own way to support different versions of the file format (perhaps with a different file extension for example).

这是一种非常简单的方法,但它有一些缺点,例如,您需要找出自己的方法来支持不同版本的文件格式(例如,可能具有不同的文件扩展名)。

Many classes in Cocoa/CocoaTouch already implement NSCoding, so they can be written to a file in this fashion (including NSArray, NSString, NSNumber, etc).

许多类可可/ CocoaTouch已经实现了NSCoding,这样他们就可以以这种方式(包括被写入文件NSArrayNSStringNSNumber,等)。

For your app, i would use this to store each radio station in a single file. When the app launches, load all the radio stations from a directory. You should consider enabling iTunes drag/drop filesharing for your app, so users can easily share radio station files with their friends or between devices.

对于您的应用程序,我将使用它来将每个广播电台存储在一个文件中。当应用程序启动时,从目录中加载所有广播电台。您应该考虑为您的应用启用 iTunes 拖放文件共享,以便用户可以轻松地与朋友或在设备之间共享广播电台文件。

This would also fit in well with iCloud for syncing between devices, I haven't looked into iCloud much, but I expect one file per radio station will be the ideal way to implement iCloud syncing.

这也非常适合用于在设备之间同步的 iCloud,我对 iCloud 的研究不多,但我希望每个广播电台一个文件将是实现 iCloud 同步的理想方式。

回答by Colin

No need for such things. If you only have like one thing to save, then research this method of NSArray:

不需要这些东西。如果你只有一件事要保存,那么研究一下 NSArray 的这个方法:

- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)flag

I your user can save many radio stations, then you might want to look into CoreData, which has a bit of a curve, but ultimately will be the easiest way.

我你的用户可以保存很多电台,那么你可能想看看 CoreData,它有点曲线,但最终将是最简单的方法。