How does a (nonatomic, strong) property's lifespan work in iOS?
Asked Answered
F

1

2

Say I have a property declared as : @property (nonatomic, strong) NSArray *menuArr; OR @property (strong) NSArray *menuArr; and set this property in viewDidLoad. How long will the device "remember" the information I have stored in the array?

The property is declared and set in a viewController that is embedded in a navigationViewController that is itself the first view controller in a TabBarViewController. In other words its the first view the user sees then they may navigate away from it and back.

Without getting into a debate over atomic vs nonatomic my question is this

Does a property (declared either way) lives on infinitely in the iOS environment or is its lifespan limited by factors such as time, memory usage elsewhere, turning off the device, etc


To avoid this being an "x y problem" here's why Im asking:

Im working on an app that includes a menu broken up into multiple categories with several items in each category .....as you might expect a menu to be. All of the menu items are stored on parse.com. At first I was doing a separate PFQuery on each page, one on the categories page to get the categories, when user selects a category a new page is pushed and a second PFQuery got all the items in the chosen category. This worked but the pages took quite a while to load, probably 10-15 seconds sometimes with no real indication that the app hadnt just frozen up.

To fix this I decided to run one PFQuery when the first view of the app is loaded in viewDidLoad getting all of the menu items and sorting the myself into nested arrays of categories containing items. I then store the menu array in a property on the viewController. Later, when I go to the menu I have the below in it's viewDidLoad:

//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;

My understanding is that this creates a pointer to the original array and does not actually create a second array (please correct me if Im wrong).

This method takes about 10-15 seconds to load and sort the array that one time but then navigation between pages is instant after that which is much better.

I plan to do queries in places to see if any menu items have been changed and if so re-download and sort the menu.

So far in my testing the app seems to remember the info in the array just fine throughout the day with normal unrelated phone usage but there has to be some limits to that right?

Fulvi answered 1/6, 2014 at 7:47 Comment(18)
These days there is almost no reason, ever to use 'nonatomic'. I'd pretty much forget about it. What was 'nonatomic'? In iOS, properties are (of course) completely safe to use with threaded programming. In ancient history, there were some obscure situations where expert programmers wanted to say: "in this case DON'T BOTHER WITH making it safe for threaded programming." Note clearly that a better word for "nonatomic' would have been something like 'unsafe' or 'thread-unsafe' or "advanced-no-thread-proptection'. It has literally no use today in normal work. So forget it.Alitta
It's very important to realise that because of copy and paste you get literally 1000s of examples of code fragments online, that still includes 'nonatomic'. It is - extremely simply - totally wrong. It's simply inconceivable you'd want to use the thread-un-safe mode. (In a handful of totally obscure - say - scientific programming situations, highly advanced engineers may have need of it. (Although that is incredibly unlikely on mobile.) In every normal app it is simply "totally wrong". Unless you want the app to crash every time it threads.)Alitta
@JoeBlow Fair enough. It seems I should be using the default of atomic. Can you offer any insight as to how the lifespan works though?Fulvi
I did not downvote this question and it seems silly anyone would downvote it - there's a rash of downvoting lately. Yes simply never use nonatomic, it's ancient history, and don't bother typing 'atomic' as everything is. Regarding "strong" use strong every time for a class (so, UIButton, NSString, your own class, or any class whatsoever). In the rare case you have a "basic" type (eg boolean, integer, etc) use assign. That's it. (It's actually now completely pointless that apple makes you type these two, as they are basically set in stone. class -- strong, bool/int/etc -- assign).Alitta
regarding the "why". i can't be bothered explaining, man :) I wouldn't worry about it :) Someone else may explain.Alitta
"and sort" it takes zero time to sort (literally a few millionths of a second), the only thing you're seeing is the networking time.Alitta
What on earth are you asking? Whether your data is going to disappear while your app is running? How could that happen and anything still function?Reneerenegade
"This worked but the pages took quite a while to load" Dude are you hip to Parse's amazing caching system? it's one of the most amazing party tricks of parse. You need to use it here, you'll be amazed. By the way, you were utterly correct to follow your heart in doing all the calls "up front" and then using it when needed.Alitta
@JoshCaswell Im asking if there is any sort of limitation to how long the app will how onto data stored in a property. I can see that the it appears to retain the property information throughout the day but will the information still be there a week from now if the app isnt opened in the meantime? Will low memory warnings elsewhere in another app perhaps cause the info to get discarded. I couldnt find any information regarding this.Fulvi
@JoeBlow that's pretty terrible advice. Nonatomic is not "ancient history" and should be the preferred property type. See #589366 for a discussion.Hallucination
lol @Josh -- where's your sense of discovery man? :) it's AWESOME that, amazingly enough, the iPhone remembers stuff!!Alitta
Hi @Hallucination ... I'm always ready to listen to ANYTHING, you rock; could you please tell me which answer you are thinking of there? (Pls do the "share" link at the bottom of answers.) The answers I'm seeing there (I may have missed one) are incredibly out of date and (today) essentially wrong. {I mean, you wouldn't say "don't use NSString! it's slow! use raw memory! here's how to allocate memory .." .. right?}Alitta
For example, @jrturton, notice Duraiam's answer there, which is totally wrong. (I added a comment at the bottom.) (The other answers from years ago are of only historic value.)Alitta
Wow it's really ... unfortunate .. that two engineers voted up the comment about nonatomic! We've never, ever, worked on any code base where nonatomic would be acceptable, from biggest to smallest dotcoms. (Everyone would just say "why?")Alitta
Old doesn't mean out of date.Hallucination
lol ill concede the merits or atomic vs nonatomic, nonatomic vs atomic, or the sun vs the moon if someone could explain if a property (declared either way) lives on infinitely in the iOS environment or it its lifespan is is limited by factors such as time, memory usage elsewhere, turning off the device, etc...Fulvi
old doesn't mean out of date? ok, sticking to the issue at hand: Nonatomic should be the preferred property type that's completely wrong. 100% wrong. You might as well say "not using ARC is the preferred approach to iOS development." completely wrong. regarding this answer https://mcmap.net/q/15346/-what-39-s-the-difference-between-the-atomic-and-nonatomic-attributes I added a comment at the bottom explaining.Alitta
Sorry, no. You're talking nonsense.Hallucination
R
5

Your app's memory space will remain valid as long as your app is running. The system is not going to arbitrarily free memory out from under you. How could your app possibly function like that? The type and attributes of the property have absolutely no relevance at this level.

A low memory warning from the system is a request that you manually free up memory that you don't need. The app's memory will either be completely as you left it, or, after moving to the background and then being terminated, a blank slate. If you have data that needs to survive your program exiting, you need to make provisions to save it to disk and read it back.

iOS does have some tricks to preserve and restore your app's state, but that still only applies to a terminated application.

Reneerenegade answered 1/6, 2014 at 8:46 Comment(1)
Thank you very much. This is exactly what I expected the case to be I just couldnt find anywhere that it was actually stated.Fulvi

© 2022 - 2024 — McMap. All rights reserved.