2017-02-22 132 views
1

我已经浏览了堆栈溢出的很多答案,但还没有找到任何回答这个问题的答案。在iOS应用程序中存储数据的最佳实践?

我有一个应用程序,您可以在downloadVC下载数据(还有很多其他的VC)。我希望能够在下载VC时访问当前用户和下载的数据,而无需重新下载数据。

我看到目前为止的选项有:

  • 制作用数据一个单,我可以在应用的各个点访问(感觉就像是最简单的方法,但人们已经警告我单身AREN”好)。
  • 制作下载VC的类var。 (这是我至少理解的解决方案,类var的范围是什么?是否与制作单例相同?)
  • 传递它(这对我来说不起作用,因为应用程序太大有它的每一个VC
  • 之间),通过将其保存到用户的默认值,(如何快速在访问一些用户默认?)

请告诉我,如果这个问题不适合堆栈溢出规则?

+0

它取决于,你想下载什么。您是否想要下载文件并将其存储在可从任何应用程序视图访问的应用程序中? – Krunal

+0

是否有并发使用downloadVC的数据? –

+0

根据“数据”的实体,答案会改变。您所下载的数据在大小方面有多大?你是否需要在没有下载它的情况下获取此下载的数据?我们需要更多的上下文 –

回答

2

单身人士通常使用一个静态变量来实现,所以你的第一个和第二个选项非常相似。

最近在开发社区有一个“单身是邪恶的”派别。

我个人认为他们有自己的位置,有时可以清理你的设计。我最近在一个由“单身人士是邪恶的”邪教组织成员设计的项目中工作,后来荒谬地将一个数据管理器对象传递给项目中的所有其他对象,导致大量开销和更多比物体掉落时的一些错误要多。

没有人回答。您需要权衡应用程序不同方法的优缺点。

虽然我会提醒不要使用UserDefaults。这是为了保存像用户偏好设置这样的小数据,而不是大数据对象。

0

这取决于文件复杂度&的大小。如果你不需要解析内容,或者它们很容易解析,但是它的大小很大,那么我建议使用Documents文件夹并从那里检索它,如果它很小或涉及复杂的处理,然后singleton代理作为经理人,我认为是合适的。

1

简单的回答是,是的,你使用单身

这是完全正确的。

注意,无论您使用

  • 的SQLite。迅速,

  • 核心数据,

  • realm.io,

  • 写入到文本文件中,

  • 一个巴斯如火力地堡或Back4app(又名解析),

  • 或者从字面上看,只是“保持阵列”(“在内存中”),

是的,你的问题的答案是你将有单身人士,这是你“保持 - 访问”的东西。完全正确。

这似乎是你在这里问的。

鉴于...

...如果你还接着问:“什么是最简单的/最佳/最现代的方式(”我的数据单“)本地存储在我的应用程序数据”时,在2017年真实世界的答案是

realm.io

您之前使用苹果公司的核心数据。 (a)壮观(b)极其困难。不过重要的是:realm.io和SQLite在上都是一样的,都可以在的Android和iOS上使用;在很多情况下,在今天的真实世界项目中,这消除了核心数据的考虑。

但是,所有这些都没有实际意义。不要忘了...

我们现在生活在一个“巴斯世界”

你不能如。 “获得编程iOS或Android的工作”。您因为您在Firebase,Parse,PubNub,Cloudbase等方面的优秀/专业知识领域而获得工作。无论是更好还是更糟糕的是,能够在Xcode,Studio中移动按钮和表格,实际上已经不是什么了。 (像GPU编程,动态网格等类似的超特殊技术是微不足道的,这是例外。)同样,假设你是一个开发自己的应用程序或启动的业余爱好者:在这种情况下,再次完全和完全关于你的后端工作。 (这同样适用于游戏或商业/社交应用程序。)根本没有“本地,静态”应用程序。 (同样,也同样适用于游戏或商业/社交应用。)

(注确实是realm.io,这是保持数据“的”简单的,明显的方式应用程式,这些天 - 事实上,这些家伙有/是我们可能都会在一年内使用Realm.io而不是Firebase。)

因此,在某种意义上,您的问题的答案是某种意义上的问题如Firebase或back4app。但是:然后在你的应用程序中,你把它集中到一个单例中,的确是(你的问题的第一部分)。

不过需要注意的....................

这是极不可能,在入门级的水平,任何的,这将是相关:只需将数据保存在一个数组中!这里的所有都是它的。好吧,一旦用户碰巧重新启动设备或应用程序,十亿年后,应用程序将重新加载数据。所以呢?

注意你的“在这里得到的数据”一个共同的名字 - 辛格尔顿是

本地

所以,

import Foundation 
often .. import SQLite, Realm, Firebase or whatever 

public let local = Local.shared 

open class Local { 
    static let shared = Local() 

    fileprivate init() { 
     print("'Local' singleton running AOK") 
    } 

    // could be this simple.. 
    var clients:[String:[Blah]] = [:] 
    var stock:[String:String] = [:] 
    func loadStockInfoFromWWW() { ... } 
    func calculateQuantityInfoOrWhatever() { ... } 

    // or it could be more like this.. 
    func reloadClientsFromParse() { ... } 
    func sendNewDataToFirebaseParse() { ... } 

    .... etc 

你然后就从任何地方访问它在你的应用程序一样

local.updateFromWeb() 
height = local.stock["ladders"][idNumber].size.h 

等等。

就是这样。

(在单code style一个字。)

+0

虽然使用单例很简单,但很少是正确的解决方案。它会导致各种潜在的问题。 – rmaddy

+0

我不像某些人那样反单身,但我也不相信单身永远是答案。同样,您对Core Data的拒绝也是夸大其词。核心数据是一个功能强大的框架,具有许多优点。确实,它不在Apple的生态系统之外提供,但这并不总是决定使用什么框架的决定性因素。 –

+0

嘿DC。你实际上必须有一个单例作为在应用程序中触摸数据的“点”。正如所说的“屏幕或指南针”是设备中的单身人士。 – Fattie

1

基本上,添加视图控制器内的任何联网的逻辑是第一个大的错误,你可以做。所以将它移到另一个只负责发送网络请求和处理响应的类。然后,当你下载了数据时,你可能需要一些东西来管理缓存 - 不管它是一组大文件还是一对小字符串,逻辑将是相同的 - 要有所有这个缓存由​​一个对象控制。这个缓存管理器可以将对象保存到本地文件,使用CoreData或者只是将这些对象保存在内存中 - 这是由您决定的,具体取决于您创建的应用程序类型。

现在,缓存管理器基本上可以是视图控制器的端点,因为它可以在请求成功后下载数据并将其返回给视图控制器,或者立即返回。视图控制器根本不需要知道任何网络。

但是,视图控制器将如何找出有关缓存管理器

你可以传递给它的引用,但你已经说过这是你的应用程序不可能的。所以基本上另一种解决方案是使用讨厌的singleton模式。我个人认为这是一种糟糕的模式,但是如果没有它,你就不能创建任何应用程序,因为你总是必须至少有一个单例,这就是AppDelegate

总之,一个好主意,可能是创建一个单独的类(或者甚至使用的AppDelegate为目的),这将是负责处理负责类之间的依赖关系网络,则高速缓存管理器 ,以及您可能需要在应用程序后面执行某些逻辑的任何其他类。这实际上是一种称为依赖注入容器的模式。它可以让你通过这个容器轻松访问你的模型类,而没有大量的单例会最终让你感到困惑,也不会创建一些传递模型对象的荒谬逻辑。

+0

@JoeBlow也许,虽然我提到了AppDelegate,但我没有说清楚,我知道事实上,单身在iOS开发中很重要(我不会写关于Android的,因为我在该领域有0经验)。但是,当涉及到设计一个好的和可持续的代码时,他们真的不应该被过度使用。另外,我认为简单的使用方式是令他们讨厌的主要原因 - 仅仅因为懒惰或缺乏经验的开发人员经常将其视为每个架构挑战的魔法解决方案。 – user3581248

相关问题