Resolved Classes, Structs & Memory Usage {Noob}

Discussion in 'iOS Programming' started by arkmannj, Jul 6, 2016.

  1. arkmannj, Jul 6, 2016
    Last edited: Jul 6, 2016

    arkmannj macrumors 65816

    arkmannj

    Joined:
    Oct 1, 2003
    Location:
    UT
    #1
    Hello,
    I have what I think are 2 simple (noob level) questions.


    The First Question

    lets see if I am understanding this correctly.
    1) I declare / create 1 Class and 1 Struct
    2) Within the Class I Instantiate the Struct
    3) Later, all references to the Class are removed
    4) Swift removes the class and frees up the resources from the Class, as well as the copy of the struct that I instantiated within the class.

    So Hypothetically speaking if the Class (without the Struct) consumed 2KB of memory, and the Struct by itself consumed 3KB of memory. (so the Class with the Struct in it consumed 5KB of memory total) When all references to the class are gone, then the system will clear up 5KB of memory right?


    Very quick example: (I'm going to omit things like init(){}, for the sake of keeping this simple at to the point of my question)
    Code:
    struct PlayerStats{ var pName = "MyName"; var pLife = 100.0; [More Code] }
    
    class Players { var MyStats = PlayerStats(); [ More Code]  } // Class Players now contains a copy of struct PlaterStats in a variable called "MyStats"
    
    var player1 = Players() //Instantiate
    
    [More Code]
    
    player1 = nil // no more references to the class "Players" so all resources including the copy of PlayerStats (in Players() called MyStats) are removed from memory.
    
    The Second Question
    I "think" I have a basic grasp on the differences in a Struct and a Class, but the best time to use each still feels fuzzy. (Struct is a Value type which means a new copy is made every time yo instantiate one, a Class is a reference type which means only the first is copied, then any other instantiations just create references to the class...right?)

    Some basic practical examples might help my brain.

    If I have a game that is spawning bad guys to fight. I'm assuming those bad guys would be structs since they each have their own stats as opposed to sharing 1 pool of stats is that right? (If I hit enemy #2 I don't want them referencing the same health level, I want them to each have their own copy) is that right?

    But perhaps level end bosses might use a class because there is only ever 1 at any time, so as long as the Boss Class stats are reset / adjusted appropriately then a class would be a good fit.

    I'm sure these are not the best examples ever, but I really am just trying to get my head wrapped around it properly.

    Thanks!
    ~Ark
     
  2. jgaz macrumors member

    jgaz

    Joined:
    Dec 30, 2007
    Location:
    Colorado
    #2
    Hi Ark,

    You are getting close here.

    For your first question you are exactly right. The PlayerStats struct is just a property of the Player so as soon as an instance of your player is deallocaed all associated properties are as well (as long as they are values like structs not objects like classes)

    For your second question you are close.

    You can think of a Struct or a Class as a blueprint for how to create some value(struct) or object(class). They only tell you how to build something of that type. So using your example; a BadGuy could really be either. With either one you could have multiple badguys who are separate but are of type BadGuy. For example:

    Code:
    Class BadGuy {
         //bad guy properties and methods
    }
    
    let badGuy1 = BadGuy()
    let badGuy2 = BadGuy()
    let badGuy3 = BadGuy()
    
    all three of the instances( badGuy1, badGuy2, badGuy3) are separate Objects built from your BadGuy Class. They have their own stats and changing the health of one wouldn't change it in another. You could so the exact same thing with a Struct.

    The difference comes after you create the instances and you want to pass them around.

    Code:
    Class BadGuy {
         //bad guy properties and methods
    }
    
    let badGuy1 = BadGuy()
    let badGuy2 = badGuy1 // both badGuy1 and badGuy2 refer to the same instance of BadGuy. changing one will change the other
    
    Struct BadGuyStruct {
         //bad guy properties and methods
    }
    
    let badGuystruct1 = BadGuyStruct()
    let badGuystruct2 = badGuyStruct1 // badGuystruct2 is a copy of badGuystruct1 but a separate instance, changing one will have no effect on the other
    
     
  3. arkmannj thread starter macrumors 65816

    arkmannj

    Joined:
    Oct 1, 2003
    Location:
    UT
    #3
    Thanks jgaz!

    Oh my goodness that really does help clarify it for me...
    Thank you so much for taking the time to explain that out, I really do appreciate it!

    ~Ark
     
  4. jgaz macrumors member

    jgaz

    Joined:
    Dec 30, 2007
    Location:
    Colorado
    #4
    no problem. Sorry I should have added that Apple suggests using structs whenever possible for a couple of reasons. First they are less memory intensive than objects. Second they avoid race conditions when you are using multiple threads as each struct is a new value. This means that you don't have to worry about it's values unexpectedly changing out from under you.

    Here are a couple of videos from WWDC the past two year on why you might prefer structs and protocols to build up you types over objects and inheritance. They are really great.

    https://developer.apple.com/videos/play/wwdc2015/408/
    https://developer.apple.com/videos/play/wwdc2016/419/

    I recently wrote this blog to show a simple example of using structs and protocols as well if you find that useful.
    https://gazlaycoding.wordpress.com/2016/07/01/protocol-oriented-programming-an-introduction/

    The Apple videos do a much better job explaining it and showing how it makes your code super easy to debug and reuse.
     

Share This Page