How do I copy objects into ivars for later use? - objective-c

Objective c | xcode | iphone question
Im building a model(data) class for a monetary transaction and have kind of a basic/noob question regarding pointers and object copying. The Transaction class I'm creating contains 4 or 5 ivars/properties that represent object type variables. now when I get the user entered data from the view controller to populate these ivars is it safe to use pointers or do i need to make a copy of the object and then assign that to the ivar?
Because I'll need to store these transactions after the user exits the program I'm assuming that any references I made to pointers in a previous session will be essentially broken links. Am i wrong here, any explanation and maybe some code examples would be appreciated.
If you have any suggestions as far as how to store the data while the app is not in use that would also be helpful.
Thanks so much,
Nick

I would suggest re-reading the intro guides as you seem to be a bit off the rails here; over-thinking the basics. No big deal, we've all been there (still are there when faced with new stuff, often!).
First, for any string value, copy it. In terms of properties, which you should use, you would want:
#property(copy) NSString *myString;
Make sure you -release myString in your -dealloc method.
For other kinds of values, it is really context dependent. Copying is often the safe route. NSDate and NSNumber instances happen to be immutable so copies are irrelevant, but free.
As far as saving data, you are semi-correct. Pointers do not remain valid/same across running sessions with your application. If you need to save data, you explicitly do so through any of a number of common mechanisms. For dead-simple data in an entirely non-document based, app specific, role, user defaults might be enough. Otherwise, see the documentation regarding archiving data.

Related

Do category names get serialized with encodeWithCoder style marshalling?

I have an app that is storing some data using the Cocoa/ObjC initWithCoder / encodeWithCoder style marshaling. Over the life of the app one of the classes that has been removed is an NSDate+Utils category.
The question is - if an NSDate+Utils is serialized to disk, and then deserialized with a later codebase when NSDate+Utils no longer exists; will it come back as an NSDate, or will it crash??
It won't crash. You just need to check whether it's nil. If that' nil, then just skip it, otherwise populate the data to your property. By the way, there is nothing to do with the codebase. It's just whether that local data being stored in the device. Codes are just things that tell device what or how to do stuff.
I wrote a small program to test this. Categories seem to get written as the base class - I assume as long as they don't add fields and/or mess with the withCoder methods.

why string, array and dictionary in Swift changed to value type

In Objc string, array and dictionary are all reference types, while in Swift they are all value types.
I want to figure out what's the reason behind the scenes, for my understanding, no matter it is a reference type or value type, the objects live in the heap in both Objc and Swift.
Was the change for making coding easier? i.e. if it is reference type then the pointer to the object might not be nil, so need to check both pointer and the object not nil for accessing the object. While if it is value type then only need to check the object itself?
But in terms of memory allocation, value types and reference types are same, right? both allocated same size of memory?
thanks
Arrays, dictionaries etc. in Objective-C are often mutable. That means when I pass an array to another method, and then that array is modified behind the back of the other method, surprising (to put it gently) behaviour will happen.
By making arrays, dictionaries etc. value types, this surprising behaviour is avoided. When you receive a Swift array, you know that nobody is going to modify it behind your back. Objects that can be modified behind your back are a major source for problems.
In reality, the Swift compiler tries to avoid unnecessary copying whenever possible. So even if it says that an array is officially copied, it doesn't mean that it is really copied.
The Swift team is very active on the official developer forums. So, I'm assuming that since you didn't ask there, you're more curious about the community's broader "sense" of what the change means, as opposed to the technical implementation details. If you want to understand exactly "why", just go ask them :)
The explanation that makes the most sense to me is that Objects should be responsible for reacting to, and updating the state of your application. Values should be the state of your application. In other words, an Array or a String or a Dictionary (and other value types) should never be responsible for responding to user input or network input or error conditions, etc. The Objects handle that and store the resulting data into those values.
One cool feature in Swift, which makes a complex Value Type (like a Dictionary or a custom type like Person, as opposed to a simple Float) more viable, is that the value types can encapsulate rules and logic because they can have functions. If I write a value type Person as a struct, then the Person struct can have a function for updating a name due to marriage, etc. That's solely concerned with the data, and not with /managing/ the state. The Objects will still decide WHEN and WHY to updating a Person's name, but the business logic of how to go about doing so safely/test-ably can be included in the Value Type itself. Hence giving you a nice way to increase isolation and reduce complexity.
In addition to the previous answers, there are also multi-threading issues to consider with sharing a Reference-Based collection type that we don't have to worry as much with sharing an instance of a type that is Value-Based and has Copy-On-Write behavior. Multi-core is becoming more and more proliferant even on iOS devices, so it has become more of an issue for the Swift language developers to consider.
I do not know, whether this is the real idea behind it, but have a historical view on it:
At the beginning, an array copy behaved by reference, when you changed an item in it. It behaved by value, when you changed the length of the array. They did it for performance reasons (less array copy). But of course this was, eh, how can I express that politly, eh, difficult with Swift at all, eh, let's call it a "do not care about a good structure if you can win some performance, you probably never need" approach. Some called that copy-on-write, what is not much more intelligent, because COW is transparent, while that behavior was not transparent. Typical Swift wording: Use a buzzword, use it the way, it fits to Swift, don't care about correctness.
Later on arrays got a complete by copy behavior, what is less confusing. (You remember, Swift was for readability. Obviously in Swift's concept, readability means "less characters to read", but does not mean "better understandable". Typical Swift wording: Use a buzzword, use it the way, it fits to Swift, don't care about correctness. Did I already mention that?)
So, I guess it is still performance plus understandable behavior probably leading to less performance. (You will better know when a copy is needed in your code and you can still do that and you get a 0-operation from Cocoa, if the source array is immutable.) Of course, they could say: "Okay, by value was a mistake, we changed that." But they will never say.
However, now arrays in Swift behave consistently. A big progress in Swift! Maybe you can call it a programming language one sunny day.

Strategy for a self-retaining and self-releasing object

I need to implement a bit of functionality that can be used from a few different places in an application. It's basically sending something over the network, but I don't need it to be attached to any particular view - I can communicate everything to the user by UIAlertViews.
What I would like to do is encapsulating the functionality in an object (?) that can maintain it's own state for a while and then disappear all by itself. I've read in several similar topics that it's generally not advised to have an object that retains and then releases itself, but on the other hand you have singletons which apart from the fact that they never get released, are very similar in nature. You don't need to keep reference to them just to use them properly. In my situation however I feel it woud be somewhat wasteful to create a singleton and then keep it alive for something that takes a few seconds to execute.
What I came up with is a static dictionary local to the class, that keeps unique references to the instances of the class, and then, when an instance is done with its task, it performs selector 'removeObjectForKey' after delay which removes the only existing reference and effectively kills the object. This way I keep only a dictionary in memory which for the most time is empty anyway.
The question is: are there any unexpected side effects of such a solution that I should be aware of and are there any other good patterns for described situation?
So basically instead of a persistent object of your own class, you've got a persistent object of type NSDictionary? How does that help matters? Is your object unusually large? If you are making your codebase more complicated for the sake of a few bytes, that's not a good tradeoff.
Especially now ARC is commonplace, this kind of trickery is usually not a good idea. Have you measured how much memory a singleton approach takes and found it to be a problem? Unless you have done this, use a singleton. It's simpler code, and all other things being equal, simpler code is far better.

Purpose of pointers

I have just started using Objective C and although I am doing okay with the pace and learning curve (I have no C background) - I don't understand one concept which is also part of C++ - Pointers!
OK - I understand that pointers point to the physical location of the actual variable rather then the value for the variable itself. When on earth can that come in handy?
Also, when to use them and when not to?
I have Googled enough but every guide I come across seems to assume that I am a PhD in rocket science.
Can someone please explain this with a simple example?
Although they are C pointers of course, I strongly suggest to understand them als references to objects.
You either create an object or receive it from somewhere and store a reference to the object in a varialbe.
When you hand the reference to the object to some function or method then this method can access the very object that you handed over. It does not nesessarily have to work with a copy of the data. If it makes changes to the ojects' properties (as far as allowed by means of the poperty declaration and stuff) then the very object is changed that your reference is referring to.
You can of course copy it and continue working with that copy when ever you think it is suitable. In that case the original object remains unchanged.
When you really come into a situation where you have to work with c-style pointers then you better step back and understand C. I donnot think it is wise understanding c-style pointers while coming from an Objecive-C background. Clear your mind and learn C from scratch and after that make use of the new know how in that very very rare situations where you have to deal with these basic data types in Objective-C projects.
One of the main reasons that pointers are used is to save memory. For example if you are passing an array to a function, it would be better to send the address in memory to the function rather than sending the values.
If you go on to do c or other lower level languages, then you will see that arrays and pointers are almost interchangeable. (C-style arrays, not NSMutableArrays in objc or vectors in c++ or lists in c# etc)
Here is a simple reason:
Imagine you have a really big object. - When you pass it to a function do you really want to copy & duplicate the entire object? - This would take a lot of CPU and memory.
By using pointers you do not have to copy the original object every time you pass it around. (Ofcourse the flipside is that if you change the object in the function it will change the original object as well).

Objective-C Multithreading and Data Containers

I have sort of a simple question. I am writing an Objective-C program with some multithreading. I have a global NSArray, and I add objects into that NSArray from a method that is called in a new thread. If the objects I add into that NSArray are new objects created in that method (local), will that create memory access and/or other issues or will the garbage collector be smart enough to keep those objects around until they have no more references? Also, if I want to an object into that NSArray, will that object be passed by reference or by value?
Can you add objects in NSArray? I guess you mean NSMutableArray.
NSMutableArray is NOT thread safe. So you may need to acquire a lock before trying to modify it. Though this will mostly dependent on how your threads are working on shared data.
NSArray or NSMutableArray will retain the objects that they contains. So after adding you can release the local copy.
The array will store the reference.
Hope it helps. In general multithreading is much more difficult than a single thread app. Please check Threading Programming Guide for the details. It may save you from many hazards.
There should be no problems with the design you're describing. All of your threads share the same memory space, so everything will work just fine. The memory management system will do "the right thing", but I recommend learning the retain/release method - there's nothing better than actually understanding what your program is doing.
Objective-C is pass-by-value only, just like C. That said, objects are only ever passed around by pointers in Objective-C, so you can think of it as always pass-by-reference in that sense.