I am trying to understand the concept of why struct vs. class have difference results. Why is the result the same here but different on structs:
import UIKit
class Message {
var internalText: String = "This is some text"
}
// create new instance
var firstMessage = Message()
//if I assign, its a reference to the original instance
var secondMessage = firstMessage
secondMessage.internalText += " with some more text added on."
//print both
print(firstMessage.internalText)
print(secondMessage.internalText)
output:
This is some text with some more text added on.
This is some text with some more text added on.
Now if you change the above from declaration from "class" to "struct"
struct Message {
var internalText: String = "This is some text"
}
...
output becomes:
This is some text
This is some text with some more text added on.
Why in the class declaration does it change the firstMessage object. Are they the same objects? Is this a rule that if I assign a new object from the old object? Then I would have to declare secondMessage = Message() to make it a new instance.
Thanks in advance.
In Swift, classes are reference types, whereas structs are value types. Value types are copied on variable assignment, whereas reference types are not.
More explanation
The system stores instantiated classes and structs into the memory. There are two main sections of the memory involved in the storage of data, the stack, and the heap. The stack contains the local variables introduced in the current method or function, and the heap is used as a kinda external memory, storing larger values. The program can only access variables stored in the stack, so a reference to the value in the heap should be held in the stack.
When you instantiate a class object by using something like Message(), a free space is reserved in your memory's heap and a reference to it is held in the stack. When you assign the same variable to a new one, the reference is copied and both variables will refer to the same bytes in the heap, so changing one changes another too.
When using structs, all the space is being reserved on the stack and there is no such thing as a pointer or reference, so when assigning to a new variable, all the data gets copied (in fact, the system is smart enough to only copy the necessary values which are being changed).
You can see a nice tutorial covering these subjects here.
Why in the class declaration does it change the firstMessage object. Are they the same objects?
The example you gave is a really nice one because it succinctly illustrates the difference between class and struct, and you came about this close -> <- to answering your own question, even if you didn't realize it. As the other answers have explained, class creates a reference type, which means that when you assign an instance of a class to a variable, that variable gets a reference to the object, not a copy of it. You said so yourself:
//if I assign, its a reference to the original instance
var secondMessage = firstMessage
In your example, firstMessage and secondMessage are really references to the one object that you created. This kind of thing is done all the time in object oriented languages because it's often important to know that you're dealing with a specific object and not a copy, especially if you might want to make changes to that object. But that also brings danger: if your code can get a reference to an object and change it, so can some other code in the program. Shared objects that can be changed create all kinds of headaches when you start writing multithreaded code. When you added text to secondMessage, firstMessage also changed because both variables refer to the same object.
Changing the declaration of Message to struct makes it a value type, where assignment (for example) creates a new copy of the object in question instead of a new reference to the same object. When you added text to secondMessage after changing Message to a struct, the assignment secondMessage = firstMessage created a copy of firstMessage, and you only changed that copy.
Is this a rule that if I assign a new object from the old object?
Whether your assignment creates a copy of the object or a reference to it depends, as you've shown, on whether the thing being assigned has reference semantics (class) or value semantics (struct). So you need to be aware of the difference, but most of the time you don't need to think too hard about it. If you're dealing with an object where you don't care about the object's identity and are mainly concerned with its contents (like a number, string, or array), expect that to be a struct. If you care about which object you're dealing with, like the front window or the current document, that'll be a class.
Then I would have to declare secondMessage = Message() to make it a new instance.
Right -- if Message is a class, assigning one to a new variable or passing it into a method won't create a new one. So again, are you more likely to care about which message you're dealing with, or what is in the message?
Simple answer: Classes are reference types Structs are value types.
In the class, firstMessage is set to Message() which is an instance of the whole class Message. So when secondMessage gets set to equal firstMessage, secondMessage Doesn’t make a new class again, it just makes a note of where firstMessage is at and they both can now operate it. But because they both in the same location, the internalText will be the same for both.
While with the struct, since they are value types, secondMessage copies all the values from firstMessage and creates its own independent object of type Message.
Classes are reference types, meaning that the firstMessage and secondMessage variables you defined in your first snippet stores only a reference to the class instance you created. Imagine your object is located somewhere in your memory heap with an id (for example, id0001), then both firstMessage and secondMessage stores only the id, which is id0001, so they both refer to the same object in memory.
On the other hand, structs are value types, meaning that the struct variables store unique objects directly; unlike reference types, no sharing is going on. So when you are assigning a new struct variable to a previous struct variable, the object gets copied, and the two variables store two unique objects with different memory addresses (IDs).
For more information, check out the official doc on classes and structs.
Let us understand the same concept with an example,
Suppose you have a google sheet in which you are adding some text and at a time you share that sheet to some other person for editing or deleting purpose. So when the other person do any changes you can see at a time. This concept is followed in class.
Moreover, classes are reference types because here you are passing a reference(sheet).
However, you have downloaded that google sheet and send its copy to another person so at that time you are not able to see the changes until and unless the person sends back the sheet. And this is the same concept followed in struct. A struct is value type because we are passing a copy(downloaded sheet).
We can inherit class but cannot inherit struct
Think of structs as a Microsoft Excel file. You create a copy and send it to me. When I change my copy, your copy doesn't get changed.
Classes on the other hand are more like Google Sheets. When I make changes to the file you shared with me, you can see the changes.
Instances of structs make copies and have different places in memory
Instances of classes point to the same place in memory
Related
Swift extensions cannot contain stored properties:
Because properties need storage, adding properties would change the
memory structure of the class
If we look closely at the runtime class struct, the Ivar list holds the property storage, and the method list also holds details about the methods that invoke the class objects. And extensions add features in the form of methods to the classes. The extraSpace in a class struct holds the extension struct. Since we can add methods to extensions this way even after the objects have been created -- and to hold the extension methods, memory has to be allocated -- why can't we add ivars?
Because extensions apply to the entire type (struct/class). ivar storage must be allocated for each instance, and instances may already have been created by the time the extension is added to the system. The metatype information can be updated; all the existing instances (which may be stored inside of other instantiated types) cannot be. There is no list of "all existing instances" that you could go and reallocate (as well as reallocating their containers).
Remember that extensions can be applied by other modules, so they may be dynamically attached whenever the module is loaded (which is not even promised to be at launch time at all, let alone before code starts running).
I am having trouble understanding my professor's lecture notes because my brain seem to treat objects, attributes, variables and class instance as interchangeable. I really appreciate any help in distinguishing these 4 terms. Thank you!
this would be helpful for u Visit https://www.quora.com/What-is-the-difference-between-instance-variable-and-class-variable
Class variables are declared with keyword static and Instance variables are declared without static keyword.
Class variables are common to all instances of a class. These variables are shared between the objects of a class. Instance variables are not shared between the objects of a class. Each instance will have their own copy of instance variables.
As class variables are common to all objects of a class, changes made to these variables through one object will reflect in another. As each object will have its own copy of instance variables, changes made to these variables through one object will not reflect in another object.
Class variables can be accessed using either class name or object reference. Instance variables can be accessed only through object reference.
https://qph.fs.quoracdn.net/main-qimg-c4b92e80a8500c11fe705c1bafc3ed26
You don't mention the programming language at question.
Usually a class is a model or template that declares
how a certain category of objects look like.
You give a class a name and you mention if it inherits
members from another class or not.
You define also the class members.
These can be variables that hold data (object state)
and methods (class defined functions) that define
the object behaviour.
When you instantiate a class using the declared model
, you get an object, that is a concrete class instance.
This is a concrete entity, think of it as a new variable in memory,
whose data type is the class (instead of for example
integer or string data types), whose value is its state
in a defined moment in time (the state being the
combination of all of its data member variables values
at that moment). This object has to have an identity,
because it exists in memory and it is a different entity
from the other objects you can instantiate from this or
any other class. The data member variables hold specific
values for each instance. These are not shared between
instances.
Now the member methods can be shared between instances
because they have no state, so they are equal for every object.
They are called with some arguments
and they do some action that changes the object state, or
is at least tightly related with the concrete object.
But they are common to every object. The methods usually
know what concrete object they act upon by means of a special
name like 'this' or 'self', that references to 'itself'.
Objects are usually assigned to variables upon creation,
storing a reference to its identity that allows the
remaining code to manipulate them.
You use these variables to refer to the concrete object
outside the code of the classes, and use 'this' or 'self'
to refer to it from inside the classes.
Frequently you access object members qualifying with the
object name. Like in 'player.run()', or 'player.total_score'.
That is if player is a variable to which you assigned a
class Player instance. This can look like player = new Player
or player = Player().
Attributes is just another name given to data members.
Sometimes attributes and also methods can be public or private,
meaning code outside the class can use them, or only
the class code can have access.
Sometimes you see data members or attributes referred as
properties. When you access an attribute, you are accessing
a property. In some languages like Python, property can mean
something a little different but close related anyway...
Now also depending on the language things can be like described
(C++, Java) or you can have everything being treated as objects,
including the class definitions (Python).
You should also search the internet or SO about
inheritance, overriding, class diagrams, and other things class
related.
This is all no more than the ability of defining your own data types
beoynd the language builtin types.
You can think of variables as names for boxes (memory containers in a certain address) holding values. But sometimes you want to manipulate
not the values but the addresses themselves. This time you say you have
references (to addresses). Sometimes variables are just names for those
references. References are also known as pointers. But you could do math with pointers (increment, decrement, add a fixed value to...) that you usually don't do with references.
I am assigning the value of a custom class to another variable. Updating the value of the new variable is affecting the value of the original variable. However, I need to stop the reference variable from updating the original variable.
Here's a basic representation of what's happening:
var originalVariable = CustomClass()
originalVariable.myProperty = originalValue
var referenceVariable = originalVariable
referenceVariable.myProperty = updatedValue
print("\(originalVariable.myProperty)") //this prints the ->updatedValue<- and not the ->originalValue<-
I've tried wrapping the referenceVariable in a struct to make it a value type but it hasn't solved the problem.
I've found information regarding value and reference types but I haven't been able to find a solution.
My question in a nutshell: How do I stop an update to a reference variable from updating the original variable that it got its value assigned from?
Thanks in advance.
The whole point of reference semantics (as used by classes) is that all variables point to the same (i.e., they reference the same) object in memory. If you don't want that behaviour, you should use value types (Struct, Enum, Array...) or create copies of your object.
If CustomClass implements the NSCopying protocol you can do:
var referenceVariable = originalVariable.copy()
If it doesn't, you'll have to find some other way to copy it or implement the protocol yourself.
Wrapping the class in a struct will just make two different structs each containing a different reference to the same object.
I have this class in which the properties are the class itself.
class Voxel {
var vertices : [Vertex] = []
var above : Voxel?
var below : Voxel?
var front : Voxel?
var back : Voxel?
var left : Voxel?
var right : Voxel?
}
It acts as a node in a Doubly 3D Linked List, but the thing is, in C and C++, I would have to store the neighbors as pointers (which I want to do to the vertex array as well).
Is this automatically done for me in Swift?
I don't see a fine way of holding an array of vertices as an array of pointers, and I certainly don't want to hold the actual values, as I'm going to have thousands of voxels.
Because Voxel is a class, a reference type, these are pointers. If it were a struct, it would be a value type and therefore each new reference would be a new copy.
By the way, be wary of strong reference cycles. Make sure one instance's implicit strong reference below is not another instance whose above is another strong reference back to the other instance. To resolve this, you'd make all of those references weak and then have some collection (e.g., a set or maybe an array or dictionary) which maintains strong references to all of the instances in the doubly linked list.
The defining characteristic of classes (vs. structs) is that they're reference types, and use reference semantics (i.e. assignment of an object only copies a reference to the object).
Classes Are Reference Types
Unlike value types, reference types are not copied when they are assigned to a variable or constant, or when they are passed to a function. Rather than a copy, a reference to the same existing instance is used instead.
Structs, on the other hand, are value types, and use value semantics (i.e. assignment of a struct copies it entirely).
Structures and Enumerations Are Value Types
A value type is a type whose value is copied when it is assigned to a variable or constant, or when it is passed to a function.
I suggest you give this a read: The Swift Programming Language (Swift 2.2)
- Classes and Structures
I already know the benefit of immutability over mutability in being able to reason about code and introducing less bugs, especially in multithreaded code. In creating structs, though, I cannot see any benefit over creating a completely immutable struct over a mutable one.
Let's have as an example of a struct that keeps some score:
struct ScoreKeeper {
var score: Int
}
In this structure I can change the value of score on an existing struct variable
var scoreKeeper = ScoreKeeper(score: 0)
scoreKeeper.score += 5
println(scoreKeeper.score)
// prints 5
The immutable version would look like this:
struct ScoreKeeper {
let score: Int
func incrementScoreBy(points: Int) -> ScoreKeeper {
return ScoreKeeper(score: self.score + points)
}
}
And its usage:
let scoreKeeper = ScoreKeeper(score: 0)
let newScoreKeeper = scoreKeeper.incrementScoreBy(5)
println(newScoreKeeper.score)
// prints 5
What I don't see is the benefit of the second approach over the first, since structs are value types. If I pass a struct around, it always gets copied. So it does not seem to matter to me if the structure has a mutable property, since other parts of the code would be working on a separate copy anyway, thus removing the problems of mutability.
I have seen some people using the second example, though, which requires more code for no apparent benefit. Is there some benefit I'm not seeing?
Different approaches will facilitate different kinds of changes to the code. An immutable structure is very similar to an immutable class object, but a mutable structure and a mutable class object are very different. Thus, code which uses an immutable structure can often be readily adapted if for some reason it becomes necessary to use a class object instead.
On the flip side, use of an immutable object will often make the code to replace a variable with a modified version more brittle in case additional properties are added to the type in question. For example, if a PhoneNumber type includes methods for AreaCode, LocalExchange, and LocalNumber and a constructor that takes those parameters, and then adds an "optional" fourth property for Extension, then code which is supposed to change the area codes of certain phone numbers by passing the new area code, LocalExchange, and LocalNumber, to the three-argument constructor will erase the Extension property of every phone number, while code which could write to AreaCode directly wouldn't have had that problem.
Your remark about copying value types is very good. Maybe this doesn't make much sense in particular language (swift) and particular compiler implementation (current version) but in general if the compiler knows for sure that the data structure is immutable, it could e.g. use reference instead of a copy behind the scenes to gain some performance improvement. This could not be done with mutable type for obvious reasons.
Even more generally speaking, limitation means information. If you limit your data structure somehow, you gain some extra knowledge about it. And extra knowledge means extra possibilities ;) Maybe the current compiler does not take advantage of them but this does not mean they are not here :)
Good analysis, especially pointing out that structs are passed by value and therefore will not be altered by other processes.
The only benefit I can see is a stylistic one by making the immutability of the element explicit.
It is more of a style to make value based types be treated on par with object based types in object oriented styles. It is more of a personal choice, and I don't see any big benefits in either of them.
In general terms, immutable objects are less costly to the system than mutable ones. Mutable objects need to have infrastructure for taking on new values, and the system has to allow for the fact that their values can change at any time.
Mutable objects are also a challenge in concurrent code because you have to guard against the value changing out from under you from another thread.
However, if you are constantly creating and destroying unique immutable objects, the overhead of creating new ones becomes costly quite quickly.
In the foundation classes, NSNumber is an immutable object. The system maintains a pool of NSNumber objects that you've used before, and under the covers, gives you back an existing number if you ask for one with the same value as one you created before.
That's about the only situation in which I could see value in using static structs - where they don't change very much and you have a fairly small pool of possible values. In that case you'd probably want to se up your class with a "factory method" that kept recently used structs around and reused them if you asked for a struct with the same value again.
Such a scheme could simplify concurrent code, as mentioned above. In that case you wouldn't have to guard against the values of your structs changing in another thread. If you were using such a struct, you could know that it would never change.