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.
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.
I read this question in stackoverflow.
The excerpt answer provided by bbum is below:
The problem isn't the assignment, it is much more likely that you
declared your instance variable to be BOOL *initialBroadcast;.
There is no reason to declare the instance variable to be a pointer
(at least not unless you really do need a C array of BOOLs).. Remove
the * from the declaration.
1.Is there anything wrong in using a pointer variable even when I do not have to maintain an array of BOOLs?
2.I think even if avoiding them a good practice, it is not specific to objective-C and applies to all programming languages which has pointers.
Please answer my questions.
1.Is there anything wrong in using a pointer variable even when I do not have to maintain an array of BOOLs?
It's not illegal to do so, but it is bad practice. Using a pointer variable requires that you manage that memory (allocate and free it), and there are whole classes of bugs that can occur as a result. If you forget to allocate the memory, or accidentally modify the pointer, your program could crash, or you could overwrite some other part of memory. If you forget to free the memory, you have a memory leak. None of these things can ever happen if you're just using a plain BOOL. In addition, you get no benefit from using a pointer here; you do a bunch of extra work, and get nothing in return.
2.I think even if avoiding them a good practice, it is not specific to objective-C and applies to all programming languages which has
pointers.
I don't know about "all programming languages which [have] pointers", but I would certainly say in any C-based language (C, C++, Objective-C), it's bad practice to use pointers to intrinsic types when a plain variable of that type will do. If you can avoid doing memory management, do so.
On a side note, it is good practice to listen to everything bbum says. Seriously.
I have some C functions that need access Instance variables. I already pass a struct in as an argument to the function, so I added pointers to the ivars to the struct.
Is it safe to rely on the pointer remaining valid throughout the life of the app (assuming i retain and release sensibly?)
The pointer remains valid as long as the thing it points to remains valid. If the object that contains the ivars gets dealloced, and someone else is still trying to use a pointer to one of the ivars, then yeah, it'll blow up.
That said, it might be a better design to just get and set the actual values as necessary; surely the ivars aren't so big that you need to point directly to them. Doing so breaks all notion of encapsulation and requires you to do a lot more error-prone work to make sure all your object lifetimes coincide. Feel free to say more or ask another question if you want more broad design advice.
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.