How does a (nonatomic, strong) property's lifespan work in iOS?
假设我有一个属性声明为:@property (nonatomic, strong) NSArray *menuArr;或@property (strong) NSArray *menuArr;,并将该属性设置为viewDidLoad。设备将"记住"存储在阵列中的信息多长时间?
属性声明并设置在嵌入到NavigationViewController中的ViewController中,后者本身就是TabbarViewController中的第一个视图控制器。换句话说,它是用户看到的第一个视图,然后他们可以离开它并返回。
在没有就原子与非原子进行辩论的情况下,我的问题是
某个属性(无论以哪种方式声明)在iOS环境中是否无限地存在,或者其寿命是否受时间、其他地方的内存使用、关闭设备等因素的限制?
为了避免这是一个"X Y问题",下面是我问的原因:
我正在开发一个应用程序,它包含一个被分成多个类别的菜单,每个类别中有几个项目……正如你所期望的那样。所有菜单项都存储在parse.com上。首先,我在每个页面上做一个单独的pfquery,一个在categories页面上获取类别,当用户选择一个类别时,一个新页面被推送,第二个pfquery获取所选类别中的所有项目。这是可行的,但页面加载需要很长时间,有时可能需要10-15秒,但没有真正的迹象表明应用程序还没有冻结。
为了解决这个问题,我决定在viewDidLoad中加载应用程序的第一个视图时运行一个pfquery,获取所有菜单项并将自己排序为包含项的嵌套类别数组。然后,我将菜单数组存储在ViewController上的一个属性中。稍后,当我进入菜单时,我看到下面的菜单是viewDidLoad:
1 2 3 4 5 6
| //get e reference to the first view controller, the one that has the menu array
FirstViewController *myVC1ref = (FirstViewController *)[[[self.navigationController.tabBarController.viewControllers objectAtIndex:0] viewControllers] objectAtIndex:0];
//set thisviewController's `menuArr` property to point to the menuArr on the first viewController.
_menuArr=myVC1ref.menuArr; |
我的理解是,这将创建指向原始数组的指针,而不是实际创建第二个数组(如果我错了,请纠正我)。
这个方法需要大约10-15秒的时间来加载和排序一次数组,但是之后页面之间的导航会立即进行,这会更好。
我计划在任何地方查询是否有任何菜单项被更改,如果是这样,请重新下载并排序菜单。
到目前为止,在我的测试中,这个应用程序似乎记住了数组中的信息,在正常情况下,与正常的手机无关,但必须有一些限制。
- 如今,几乎没有理由使用"非原子"。我几乎忘记了这件事。什么是"非原子"?在IOS中,属性(当然)与线程编程一起使用是完全安全的。在古代历史上,有一些模糊的情况,专家程序员想说:"在这种情况下,不必担心线程编程的安全性。"显然,"非原子"的更好的词可能是"不安全"或"线程不安全"或"高级无线程支持"之类的东西。在正常工作中,它今天毫无用处。所以忘掉它吧。
- 很重要的一点是要认识到,由于复制和粘贴,你可以在网上得到1000多个代码片段的实例,其中仍然包括"非原子的"。这是-非常简单-完全错误的。你想使用线程非安全模式简直是不可思议。(在一些完全不清楚的,比如说科学的编程环境中,高级工程师可能需要它。(尽管这在手机上不太可能。)在每个正常的应用程序中,它都是"完全错误的"。除非您希望应用程序在每次运行时崩溃。)
- @乔布吹得够公平的。似乎我应该使用原子的默认值。但是,你能提供一些关于寿命是如何工作的见解吗?
- 我没有投反对票,似乎很傻,任何人都会投反对票——最近出现了一系列的反对票。是的,绝对不要使用非原子的,这是古老的历史,不要像一切一样麻烦地输入"原子"。关于"strong",每次对一个类使用strong(所以,uibutton、nsstring、您自己的类或任何类)。在极少数情况下,您有一个"基本"类型(例如布尔值、整数等)使用assign。就是这样。(事实上,苹果公司让你输入这两种类型是毫无意义的,因为它们基本上都是石头做的。class——强,bool/int/etc——赋值)。
- 关于"为什么"。我不必费心解释,伙计:)我不会担心的:)别人可以解释。
- "和排序"排序需要零时间(字面上是几百万分之一秒),你唯一看到的是网络时间。
- 你到底在问什么?当你的应用程序运行时,你的数据是否会消失?怎么会发生这种情况,任何事情都会继续起作用?
- "这很管用,但是页面加载花了很长时间,"伙计,你对Parse神奇的缓存系统感兴趣吗?这是解析的最神奇的聚会技巧之一。你需要在这里使用它,你会很惊讶的。顺便说一句,你完全正确地跟随你的心做所有的呼叫"预先",然后在需要的时候使用它。
- @乔希·卡斯韦尔(Joshcaswell)问我,应用程序将如何处理存储在属性中的数据有没有任何限制。我可以看到,它似乎一整天都在保留财产信息,但如果在此期间不打开应用程序,从现在起一周后信息还会存在吗?其他应用程序中的内存不足警告是否会导致信息被丢弃?我找不到任何有关这方面的信息。
- @乔布,这是个很糟糕的建议。非原子的不是"古代历史",应该是首选的财产类型。有关讨论,请参阅stackoverflow.com/questions/588866/…。
- lol@josh——你的发现感在哪里?:)令人惊讶的是,iPhone还记得一些东西!!
- 嗨@jrturton…我随时准备听任何东西,你这个笨蛋,你能告诉我你在想什么答案吗?(请做答案底部的"分享"链接。)我看到的答案(我可能错过了一个)非常过时,(今天)基本上是错误的。我的意思是,你不会说"不要使用nsstring!太慢了!使用原始内存!以下是如何分配内存…..正确的?}
- 例如,@jrturton,注意到Duriam的答案,这是完全错误的。(我在底部添加了一条评论。)(其他几年前的答案只有历史价值。)
- 哇,真的……不幸的那两位工程师投票否决了关于非原子的评论!我们从来没有在任何可以接受非原子性的代码基础上工作过,从最大到最小的dotcom。(每个人都会说"为什么?")
- 旧并不意味着过时。
- 如果有人能解释某个属性(不管是以哪种方式声明的)在iOS环境中无限地存在,或者它的寿命受到诸如时间、其他地方的内存使用、关闭设备等因素的限制,那么lol将承认它的优点或原子对非原子、非原子对原子、太阳对月球,或者太阳对月球。
- 永远活下去
- 旧并不意味着过时?好的,坚持手头的问题:非原子属性应该是完全错误的首选属性类型。100%错了。你也可以说"不使用ARC是iOS开发的首选方法。"完全错误。关于这个答案stackoverflow.com/a/17571453/294884,我在底部添加了一个注释解释。
- 对不起,不,你说的是废话。
只要您的应用程序正在运行,您的应用程序的内存空间将保持有效。系统不会随意地从你的下面释放内存。你的应用程序怎么可能像那样运行?属性的类型和属性在这个级别上绝对没有关联性。
来自系统的内存不足警告是您手动释放不需要的内存的请求。这个应用的内存要么在你离开的时候就完全存储了,要么在移到后台然后被终止之后,变成了一块空白的石板。如果您的数据需要在程序退出后继续存在,那么您需要做出准备,将其保存到磁盘上并将其读回来。
iOS确实有一些技巧可以保留和恢复应用程序的状态,但这仍然只适用于终止的应用程序。
- 非常感谢你。这正是我所期望的情况,我只是找不到任何地方,它实际上是说。