Can I get a small explanation about this bit of code?

Discussion in 'iOS Programming' started by Tander, Jun 12, 2013.

  1. Tander macrumors 6502a

    Tander

    Joined:
    Oct 21, 2011
    Location:
    Johannesburg, South Africa
    #1
    Hey guys,

    So I am busy reading an objective-c book by Big Nerd Ranch. I'm on chapter 17 at the moment and managed to complete the required challenge at the end of the chapter. However, I just have two question that I would like to understand.


    In the following bit of code - StockHolding is a custom class that has instance variables and the stocks (an array) points to three instances of stockholding with values setting its stock value and cost in dollars.

    At first I tried to access the array to get the data from the objects it pointed to - but it seems that was not going to work as the array doesn't know what data its objects contain - just where they are in memory, right?

    What I want to know is why was it necessary to create a new instance of stockholding (holdings) in this for loop to access those variables?
    How does the new instance of stockholding know what the values of my stocks are?

    Code:
    
            for (StockHolding *holdings in stocks){
    
                NSLog (@ "%@ has %d shares. Cost: $%.2f. Stock value: $%.2f", [holdings stockName],
    [holdings numberOfShares], 
    [holdings costInDollars], 
    [holdings valueInDollars]);
            }
    
    I'm going to try have a guess here to see if maybe I understand it a little better?

    We create an instance of our class in the for loop so that we have access to its instance methods and variables - then we use the stocks array to get the variables from those objects in the array?

    I may be completely off.. :(

    Any advice?

    Thanks guys!
     
  2. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #2
    You are confusing instances with variable names. holdings is not an instance. It points to an instance. A pre-existing instance. Not a new one. Each iteration through the loop the pointer is updated to point at the next instance from the collection stocks.
     
  3. dantastic macrumors 6502

    dantastic

    Joined:
    Jan 21, 2011
    #3
    What you have there is called Fast Enumeration. It's a way of iterating through an array really fast. You are not creating a new instance of StockHolding you are merely accessing an existing instance from the array.

    You can have a peek here under fast enumeration https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/FoundationTypesandCollections/FoundationTypesandCollections.html

    Code:
    for (NSString *myString in allMyStrings) {
        NSLog(@"String: %@", myString);
    }
    
    for (int i = 0; i < allMyStrings.count; i++) {
        NSString *myString = [allMyStrings objectAtIndex:i];
        NSLog(@"String: %@", myString);
    }
    
    These two loops provide the same functionality but the former one is much faster. If you look at the second loop, you are just accessing the object, not creating a new instance.
     
  4. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #4
    Can you prove the former is faster? I honestly believe it won't be faster. My understanding is the name is related to it being faster to type rather then faster to execute.
     
  5. dantastic macrumors 6502

    dantastic

    Joined:
    Jan 21, 2011
    #5
    Let's not take my word for it.
    Code:
    	NSMutableArray *myArray = [[NSMutableArray alloc] init];
    	for (int i = 0; i < 10000000; i++) {
    		[myArray addObject:[NSString stringWithFormat:@"String %i", i]];
    	}
    	
    	NSDate *t0 = [NSDate date];
    	NSMutableArray *forArray = [[NSMutableArray alloc] init];
    	for (int i = 0; i < myArray.count; i++) {
    		
    		NSString *myString = [myArray objectAtIndex:i];
    		[forArray addObject:[myString copy]];
    	}
    	NSDate *t1 = [NSDate date];
    	
    
    	NSDate *t2 = [NSDate date];
    	NSMutableArray *enumArray = [[NSMutableArray alloc] init];
    	for (NSString *myString in myArray) {
    		
    		[enumArray addObject:[myString copy]];
    	}
    	NSDate *t3 = [NSDate date];
    	
    	
    	NSLog(@"\nFor loop: %f\nEnum loop: %f", [t1 timeIntervalSinceDate:t0], [t3 timeIntervalSinceDate:t2]);
    
    Code:
    For loop: 2.092580
    Enum loop: 1.366328
    
    That's pretty significant I recon.
     
  6. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #6
    Cool: I know in Java tests have shown that using the Iterator is slower than a straight for loop. I would be interested in seeing the results if you saved the count into a variable instead of checking it every iteration of the for loop...
     
  7. dantastic macrumors 6502

    dantastic

    Joined:
    Jan 21, 2011
    #7
    Modified the code slightly to read the count of the array into an int before setting the t0 time stamp and then using the int instead of querying the array.count.

    Code:
    For loop: 1.946401
    Enum loop: 1.407935
    
    It did improve the result. Considering as well the fast enumeration loop was slightly slower this time the for loop can be considered improved a good bit.
     
  8. Tander thread starter macrumors 6502a

    Tander

    Joined:
    Oct 21, 2011
    Location:
    Johannesburg, South Africa
    #8
    Okay so we are point at the instance of stockholding using the pointer *holdings. That clears it up a little. :)

    When you say pre-existing instance - is that stockholding you're referring it?
     
  9. Tander thread starter macrumors 6502a

    Tander

    Joined:
    Oct 21, 2011
    Location:
    Johannesburg, South Africa
    #9
    Thanks - the link does help. So what I get from that is we point to each object in the array, using the instance stockholding and we call this instance holdings. Which is why [holdings currentSharePrice] works in the NSLog function, right?

    Since currentSharePrice is an instance variable inside our stockholding class - so we can now access it using an instance of the class?
     
  10. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #10
    stocks contains a number of instances of StockHolding. Instances don't have names: it makes no sense to ask if an instance is "stockholding" or any other name. Instances do, however, have memory addresses.

    If we step aware from Objective-C for a bit and pretend that stocks is a plain old array (not a NSArray which I assume it is). An array is a contiguous block of memory starting at an address like this:
    Code:
    Memory:   0000 0001 .... 0100
    Contents: [       ] [       ]  [       ]
    
    If this is an integer array then the contents could be numbers:

    Code:
    Memory:   0000 0001 .... 0100
    Contents: [   1] [  5]      [-10]
    
    So far, so simple. But what if our array contains pointers:

    Code:
    Memory:   0000   0001    .... 0100
    Contents: [1001] [1100]      [1111]
    
    So now the first element of our array does not contain a value: it contains a pointer to a value. This is the situation we have in this example. An instance of any class is simply a structure in memory. This structure is, in reality, quite complicated but we can simplify it to something like this:

    Code:
    Offset Item
    0        isa
    1        1st instance variable
    2        2nd instance variable
    ....
    
    where isa is a pointer to the class and the rest are the instance variables. These will either be the raw value in the case of primative types or a pointer to another object in the case of object types.

    When we create the array stocks what is actually happening is something like this:

    Code:
    Stocks: [00100000, 00100010, 00100111]
    0010000: isa pointer -> StockHolding class
    0010001: 100
    0010010: isa pointer -> StockHolding class
    0010011: 400
    0010100: isa pointer -> StockHolding class
    0010101: -200
    
    So we have an array which contains 3 pointers. These pointers point to 3 instances of StockHolding (3 memory addresses). Each of these objects has a single instance variable, the amount of the holding for this instance (100, 400 and -200). As we loop over the array holdings points first to 0010000 then the second time 0010010 and the third time 0010100. So it points to the existing instances, not new ones. When we as for the holding amount we get the amount from the instance we are pointing at: instance variables are at an instance level, not the class level:

    Code:
    StockHolding a = [[StockHolding alloc] init];
    [a setSharePrice:100];
    StockHolding b = a; // so now b and a point to the same instance
    [b setSharePrice:200];
    NSLog(@"%i",[a getSharePrice]);
    
    200 will be printed as both a and b point to the same instance: they point to the same object in memory.
     
  11. Tander thread starter macrumors 6502a

    Tander

    Joined:
    Oct 21, 2011
    Location:
    Johannesburg, South Africa
    #11
    Okay that is making a lot more sense now. :cool:

    I really appreciate the time you have taken in explaining this to me.
    Doing this on my own with no one around who knows objective-c is difficult as I have to do a lot of the research on my own.

    I am going to re-read your explanation again tomorrow as I am tired today so I don't think I am "absorbing" as much as I could be at this point in time.
     
  12. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #12
    This is probably a good idea. Sometimes stepping away and coming back makes everything just snap into place. The one thing I would suggest is learning plain old C. Pointers, memory etc are all based on that and a good understanding of that could help here.
     
  13. Tander thread starter macrumors 6502a

    Tander

    Joined:
    Oct 21, 2011
    Location:
    Johannesburg, South Africa
    #13
    Yeah I think I need to revisit the pointers section of my book. :(
     
  14. Duncan C macrumors 6502a

    Duncan C

    Joined:
    Jan 21, 2008
    Location:
    Northern Virginia
    #14

    Definitely.

    The take-away is this:

    Any variable with a "*" in it's declaration is a pointer variable. It's a memory address that points to something else.

    Example:
    Code:
    MyObject *anObject;
    anObject = [[MyObject alloc] init];
    
    anObject is a pointer variable that points to an object of type MyObject.

    Note the asterisk in the declaration.


    After the first declaration line, the pointer anObject may point to garbage memory, or to nil, depending on how your compiler is set up.

    The RIGHT PART of the second line creates a new MyObject, initializes it, and returns it. The "=" operator then saves the result into the local POINTER variable anObject.

    After that second line, the local variable anObject contains the address of a MyObject object.

    In practice, everybody says "anObject contains the newly created object" because it's easier to say, but it's not really correct.


    That is different than this line:

    Code:
    int anInt;
    
    Note that there is no asterisk in the declaration of anInt.

    Ih that code, the variable anInt actually holds an integer value, not a pointer. The compiler defines anInt as a block of memory that can hold an integer.
     
  15. Tander thread starter macrumors 6502a

    Tander

    Joined:
    Oct 21, 2011
    Location:
    Johannesburg, South Africa
    #15
    Hi Guys,

    Okay so I have re-read both / all explanations and it's starting to be much clearer now.

    I'm going to reread pointers and make sure I try understand them 100%.

    Is it okay if I keep this thread open to discuss any question I may have regarding pointers in general and to see if my understanding is correct once I have reread about pointers in general?

    Thanks again all! :cool:
     
  16. Tander thread starter macrumors 6502a

    Tander

    Joined:
    Oct 21, 2011
    Location:
    Johannesburg, South Africa
    #16
    I've decided to read a book called: The C Programming Language by Brian W. Kernighan and Dennis M. Ritchie - while also reading my current book, too.
    BNR Objective-C programming

    Maybe side by side they will make sense.
     
  17. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #17
    That is, essentially, the C book. The OG if you like.
     
  18. dantastic macrumors 6502

    dantastic

    Joined:
    Jan 21, 2011
    #18
    You just have to say K&R - that's it. I recon most of us have a copy within reach.
     
  19. Tander thread starter macrumors 6502a

    Tander

    Joined:
    Oct 21, 2011
    Location:
    Johannesburg, South Africa
    #19
    Is the K&R book that good?

    I see there is a second edition with around 200-odd pages.

    As a total beginner would I struggle with this book?
    Also can I use xCode to compile / run the examples / exercises in the book on?
     
  20. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #20
    It is the book written by the guys who designed an implemented C. As such it has everything. The book recommended when I was at Uni was "A Book on C" by Kelly and Pohl. It was good enough to learn from
     
  21. Tander thread starter macrumors 6502a

    Tander

    Joined:
    Oct 21, 2011
    Location:
    Johannesburg, South Africa
    #21
    Having done a little C (From current book ) - maybe I should just read THE book of C and see how it goes?

    If I find it difficult maybe I will get another book with a different learning style.
     
  22. Duncan C macrumors 6502a

    Duncan C

    Joined:
    Jan 21, 2008
    Location:
    Northern Virginia
    #22
    I've read both the K&R book and the "A book on C" book by Kelly and Pohl. The K&R book is better written.

    K&R is very clear and well written. It requires work from you in order to learn from it. If you read the entire teaching section of the book and do all the exercises, you will have a good working knowledge of C (including pointers) when you are done.
     
  23. Tander thread starter macrumors 6502a

    Tander

    Joined:
    Oct 21, 2011
    Location:
    Johannesburg, South Africa
    #23
    Thanks Duncan. Would you say it's better to put down the Objective-C book and pickup the K&R book and finish it. Then carry on with the OC book?
    Or side by side?

    Was planning on reading both on a per chapter basics. So read chapter one of the K&R book. Then read the current chapter that I am on with the second book - rinse and repeat?
     
  24. Duncan C macrumors 6502a

    Duncan C

    Joined:
    Jan 21, 2008
    Location:
    Northern Virginia
    #24
    If you were reading the Big Nerd Ranch Objective C book I would say you could just read that book, as the first several chapters teach you a crash course in C.

    I'm not as familiar with the other book even though I own it. (I teach classes on this stuff sometimes so I have quite a few books at different levels.)

    I would not suggest reading a chapter of K&R, then a chapter of Objective C, then another chapter of K&R. That's going to leave you very confused.

    If you're going to study C, read the entire K&R teaching section and do all the exercises, including creating linked lists, etc. If you do that, you will have not only a solid grounding in C, but a solid grounding in computer science. If I remember correctly, it goes through exercises in Linked Lists, binary trees, stacks, etc. Great fundamentals that many people starting out never get.

    Expect it to hurt your head more than a little. Remember that by reading all of K&R you're covering a lot of the fundamentals of computer science, written by the guys who created UNIX and C.
     
  25. Tander thread starter macrumors 6502a

    Tander

    Joined:
    Oct 21, 2011
    Location:
    Johannesburg, South Africa
    #25
    Thanks Duncan.

    I'll finish the BNR book first and will start K&R book as weekend project (IE read it every weekend) as I cannot read it while at work as I have some deadlines to meet.

    With regards to that K&R book - is it possible to follow it properly on my MacBook using xCode - or will I need a different compiler?
     

Share This Page