Amazon.com Widgets initWith: - Chap 10, pg 206, Prog 10.1
Welcome, Guest. Please login or register.
Did you miss your activation email?
April 23, 2014, 05:39:11 PM
Home Help Search chat Login Register 
News: Read this please.The Great Kangaroo Escape Looking for reviews of the 4th ed on Amazon!   Twitter:  @skochan
                     

+ Official Forum for Programming in Objective-C (the iPhone Programming Language) - Stephen Kochan
|-+ Old Stuff
| |-+ Chapter Study
| | |-+ Chapter 10 - More on Variables and Data Types
| | | |-+ initWith: - Chap 10, pg 206, Prog 10.1
Pages: [1] 2 Go Down
Print
Author Topic: initWith: - Chap 10, pg 206, Prog 10.1 (Read 5288 times)
hdelman
Newbie
*
Posts: 21






on: April 27, 2009, 04:43:49 PM

No matter how many times I've read and thought about it, I just can't make sense of the method initWith:.

Looking at program 10.1...  the third line of main is

Code: (Objective-C)
a = [[Fraction alloc] initWith: 1: 3];

I interpret this in this way...

    1.  A message, alloc, is sent the Fraction class to alloc memory for a new object.
    2.  The message returns a pointer to the allocated object.
    3.  A message, initWith::, is sent to the newly allocated object.

The first line of initWith is

         
Code: (Objective-C)
self = [super init];

and this is where I get lost.  My understanding is that the receiver of the message [super init] is the NSObject class, since we are sending it from a Fraction class object.  So what does that have to do the newly allocated Fraction object?  And is it okay to keep sending init messages over and over again, as we do in the following line of program 10.1?  It would seem to me that that would risk messing up other subclasses of NSObject.

Can you help me to see what am I not getting here?

Thanks,
Howard



Logged
skochan
Administrator
Hero Member
*****
Posts: 3114







Reply #1 on: April 27, 2009, 05:36:33 PM

A class inherits methods and instance variables from its parent.    You don't necessarily know what instance variables are inherited or how they should be initialized.  If you write your own initialization method (and therefore you don't use the inherited one), you have to make sure the instance gets fully initialized.  That's done by invoking init on super.  You're basically saying, "Initialize your stuff and then I'll take care of mine."

Hope this helps!


Cheers,


Steve
Last Edit: April 27, 2009, 05:38:25 PM by skochan Logged
hdelman
Newbie
*
Posts: 21






Reply #2 on: April 27, 2009, 06:26:12 PM

So does the message
Code: (Objective-C)
[super init]
mean that NSObject initializes whatever variables within the newly created Fraction class object were inherited from NSObject?  And by extenstion...  it leaves alone inherited variables in other Fraction class objects?



Logged
skochan
Administrator
Hero Member
*****
Posts: 3114







Reply #3 on: April 27, 2009, 06:43:01 PM

super doesn't know about your class.  You inherit from it, not the other way around.

Cheers,

Steve
Logged
hdelman
Newbie
*
Posts: 21






Reply #4 on: April 27, 2009, 06:56:18 PM

Well, then I really am not understanding this.  Exactly what variables are affected by [super init]?  I understand that the Fraction class, as we have defined it, contains more variables other than just numerator and denominator.  But if super doesn't know about my class, then how can it initialize the variables that Fraction has inherited?

Or to put it another way, how are the variables, other than numerator and denominator, in the Fraction class initialized?

Howard
Logged
skochan
Administrator
Hero Member
*****
Posts: 3114







Reply #5 on: April 27, 2009, 07:22:02 PM

Quote
Or to put it another way, how are the variables, other than numerator and denominator, in the Fraction class initialized?

Those inherited variables are set to zero by default (I believe that's actually done when the object gets allocated; the allocated space gets set to zero).  If NSObject needs to set a particular variable in the Fraction class object (such as the isa variable), it will do so when its init method is invoked.  Here's the thing.  NSObject's init method doesn't know or care about your added instance variables.  They've simply been tacked onto the object.  If you want to initialize your newly-added instance variables to a nonzero value, you do that by overriding init (or writing your own init...), calling super to do its thing and then taking care of setting your own variables (or setting some or all of the inherited ones to different values)

Howard, I don't think I can explain this any other way.  :-)  If it's still not clear, continue to ask and maybe another member can take a stab at it.   

Cheers,

Steve Kochan

Logged
hdelman
Newbie
*
Posts: 21






Reply #6 on: April 27, 2009, 09:16:12 PM

Steve,

Thanks for your help.  I understand it can be frustrating sometimes to explain things with words, rather than being able to have a face to face conversation.  I do appreciate your efforts.

I am still having a problem understanding which class needs to perform which methods on which object.  As I took a break for dinner, I started thinking about it in a different way.  Please allow me one more try to explain my confusion.

Up to this point, when I created a new object by writing [Fraction alloc] init], I understood that the init method was inherited from NSObject.  I also understood that the receiver of the init message was the newly allocated object from the Fraction class.  This all made sense.

Now, you've taught me about writing my own initialization methods, e.g. - initWith:.  The first line of initWith: contains the message [super init].  What is confusing me is why the message is not  [self init], which in my way of thinking, would be equivalent to what we have been doing up to now with [Fraction alloc] init]?

If I understand correctly [super init] and [self init] would both use the same init method, inherited from NSObject in the case of [self init].  Why has it been okay, up to this point, to send the init message to the newly created Fraction class object, but with initWith:, I need to send the message to NSObject?

Howard
Logged
skochan
Administrator
Hero Member
*****
Posts: 3114







Reply #7 on: April 27, 2009, 09:26:55 PM

Howard,

If you override init and then do a [self init], you would end up calling yourself recursively, so that's the reason you can't do it if you override the init method.  And in general you don't want to do it, because you may recall that the designated initializer is typically the one with the most arguments.  So if overrode the init method and it called the initWith:: method, you would again end up in a loop if your initWith:: method did a [self init].   

Are we getting closer?  :-)

Cheers,

Steve
Logged
hdelman
Newbie
*
Posts: 21






Reply #8 on: April 27, 2009, 09:51:37 PM

I must not have been clear.  I am not overriding init.  I am just defining a new method initWith:.

Howard
Logged
skochan
Administrator
Hero Member
*****
Posts: 3114







Reply #9 on: April 28, 2009, 09:13:32 AM

No, you were clear.  I was trying to say that it's not good programming practice to do a [self init] and to give the reasons why that could lead to trouble.

Steve Kochan
Logged
hdelman
Newbie
*
Posts: 21






Reply #10 on: April 28, 2009, 09:31:53 AM

Understand.  Thanks again for all of your efforts.

Howard
Logged
adamgonzalez1984
Jr. Member
**
Posts: 89






Reply #11 on: April 28, 2009, 09:53:21 AM

So here's what my understanding is about this conversation...

the code:

Code: (Objective-C)
self = [super init]

calls the NSObject's init method which we have been using since the beginning with
Code: (Objective-C)
[[Fraction alloc] init];

but since we want to create an initWith:: method we have to use the NSObjects init method (which is where the [super init] comes in) and extend it by invoking the init method and override it by adding this.....

Code: (Objective-C)
 if (self)
    [self setTo: n over: d];

so now we have our own init method, which uses NSObject's init method, but its now it's extended to include the setTo: over: method all in one line of code:

Code: (Objective-C)
Fraction *aFraction =[[Fraction alloc] initWith: 1 over: 3];


Does this make sense?  I'm not really sure if I put it the right way.  If I didn't then don't mind me I'm just sticking my foot in my mouth. 

Thanks,
Adam
Logged
hdelman
Newbie
*
Posts: 21






Reply #12 on: April 28, 2009, 10:10:32 AM

Adam,

Thanks for adding to the conversation.  I understand what you wrote.  And thanks to Steve's patience, I now understand why I can't continue using [[Fraction alloc] init] if I create any new initialization methods, such as initWith:.  I also understand that when, up to this point, I wrote [[Fraction alloc] init], that the init method was inherited from NSObject. 

I guess what is still bugging me is this:  With [[Fraction alloc] init], the message to use the init method is being sent to our newly allocated instance of a Fraction class object.  So presumably, it "knows" all about itself, its variables, its requirements for initialization, etc.  But if I write self = [super init], then the message to use the init method is being sent to NSObject.  But NSObject doesn't know anything about my instances.  So how does it know what needs to be initalized?

Howard
Logged
skochan
Administrator
Hero Member
*****
Posts: 3114







Reply #13 on: April 28, 2009, 10:46:35 AM

Quote
But if I write self = [super init], then the message to use the init method is being sent to NSObject.  But NSObject doesn't know anything about my instances.  So how does it know what needs to be initalized?

Everything gets zeroed out by default.  And as noted, I believe this is done by the alloc method and not even by init.  Remember, the init method that the Fraction class would use anyway if you don't override it is the one that is inherited from NSObject; it doesn't get changed, it gets inherited as is.  This only matters when you need an init routine to do something special, such as set one or more instance variables to some value other than zero, or allocate an array, or an origin, for example.  If the init routine doesn't need to do anything special, then it's just fine to use the inherited one.

Somehow I have a feeling that's not going to clear it up....   Smiley

Cheers,

Steve
Logged
dharr19
Full Member
***
Posts: 175


Email




Reply #14 on: November 30, 2010, 08:18:52 PM

Hi Stephen,

I see what your saying.  The fraction class is init normally first by self = [super init], then because we have an initWith message we end up re-initializing those instance variables to whatever we want to using the initWith method.  Does that about sum it up?

Thanks
David
Logged
Pages: [1] 2 Go Up
Print
Jump to:



Login with username, password and session length

Powered by MySQL Powered by PHP Powered by SMF 1.1.11 | SMF © 2006-2009, Simple Machines LLC Valid XHTML 1.0! Valid CSS!
Entire forum contents (c) 2009 classroomM.com. All rights reserved.