Re: beginning Obj-C [LONG]
Re: beginning Obj-C [LONG]
- Subject: Re: beginning Obj-C [LONG]
- From: David Elliott <email@hidden>
- Date: Thu, 7 Aug 2003 17:53:54 -0400
On Thursday, August 7, 2003, at 06:17 AM, David Thorp wrote:
Greetings again all...
Firstly, this is rather long, and for that I apologise. If you don't
read it I won't be offended :-)
Secondly, one person on this list emailed me privately to ask me to
find another forum for seeking help with my C questions. I'm inclined
to disagree with that suggestion, but I don't want to upset anyone so
I've tried to limit the questions anyway. Thankfully though, I think
I'm pretty clear on C now anyway.
It probably would be better to find a different forum for plain C
questions, this is a fairly high traffic list.
Since you really don't need to know the C library to do Objective-C
programming, you can avoid all of the crap about C strings and
concentrate on learning the basic types and flow control structures,
which you seem to have mostly done now. I think your questions about
Objective-C are pertinent enough for this forum, so I'm going to go
ahead and answer.
Besides, it's boring reading a ton of messages about this and that GUI
feature, sometimes it's nice to remember the basics of the language
you're coding in.
History:
As most of you probably know by now I'm on the learning path from
having done a Pascal and "good programming techniques" course at
university 10 years ago, then spent 10 years programming in FileMaker,
to now deciding to learn Cocoa and do some "real" :-) Mac programming.
I'll assume you can still program after having used Pascal. I have my
doubts.
;-)
C (like most languages) has built in types. We declare variables of a
certain type, and then give values to (initialize) them eg:
int age; //declaration
age = 30; //initialization
A particular kind of type that is very useful of course is a struct - i
see that as a programmer-definable type - would that be accurate?
Yes, that would be accurate. A struct is simply a programmer-defined
type composed of other types.
Now... objects/classes. Conceptually, I'm currently thinking of an
object as like a glorified struct (programmer-definable type). A
struct has to be defined, but after that it's like any other type - we
declare the variables and then initialize them (as outlined above).
Like a sruct, an object is essentally a set of variables (data
structure) and then some. (I realise that unlike a struct an object
has a set of methods to tell the data what to do. And the data
structure is hidden from outside of the object - instead accessed only
through the methods. All combined, it makes up an object. - I
appreciate there's a lot more to it than that, but go with me for a
second if that's ok). Is this all pretty much right so far?
An object is a special type of struct (see below). Furthermore, in
Objective-C objects are always used via pointers (you'll see why below).
Now, I lost it right on page 56 I think (second page of chapter 3) with
"id". Although perhaps I am just grasping it. I'm beginning to think
the idea of:
id anObject;
might be like saying
variable age;
but not saying what type (int, char, whatever) of variable it is. Then
at a later time in the program, I can somehow tell the program that
this particular age variable for the time being can be an int. But
then later maybe it can be a float or char instead. I realise of
course that that's not normally done in C, I'm just using it as an
analogy.
Err... sort of. You have now run in to what makes Objective-C
different from plain C. Objective-C is C with a runtime system "tacked
on" if you will.
The analogy is: Is saying "id anObject;" merely declaring an object
without saying what type of object it is, simply because objective-C
allows us to change what type of object it might be during runtime? Is
that it?
[snip]
A secondary question is: I also note, that (at least in the pdf) it
declares "id anObject;" (no * to indicate pointer) but "Rectangle
*myRect;" (with a * to indicate pointer) why the * in "Rectangle
*myRect;" but none in "id anObject;"? (Although that again may be
because I've completely misunderstood).
Now you're getting somewhere. Look in /usr/include/objc/objc.h among
others in that same directory.
Notice that "id" is actually a typedef for "struct objc_object*".
Don't let the fact that it's all declared in the same statement confuse
you. While you're looking at that, look at what struct objc_object* is
defined as. It simply contains one variable of type "Class" named
"isa". Class, in turn, is another pointer to an instance of a struct
objc_class.
So, that's why if you assign a variable of type NSView* to a variable
of type id, anything involving the Objective-C runtime can still work.
Specifically, all Objective-C objects are made up of a struct-like
object with that same "Class isa;" at the top. Because what's pointed
to by the isa variable describes everything the Objective-C runtime
needs, the runtime's only requirement is that isa point to the instance
of struct objc_class that describes the class. For every class
implemented (i.e. @implement ClassName), the compiler will create one
instance of struct objc_class and fill it with info about the class.
For every instance of a class created (e.g. through [ObjectType
alloc]), the compiler will create a struct-like object whose first
member will be that Class isa;. Keep in mind that when deriving
classes, the beginning of the struct-like object is the struct-like
object it was derived from. That is, since NSObject has Class isa; as
its first member, all objects derived from NSObject have it as their
first member.
In more concrete terms:
typedef struct objc_class *Class;
struct objc_object {
Class isa;
};
And the internals of NSObject look something like this:
struct NSObject {
Class isa; // points to the class defintion of NSObject
// whatever other NSObject instance variables there may be
};
And the internals of an NSObject derived class (say, NSResponder):
struct NSResponder {
Class isa; // points to the class definition of NSResponder
// whatever other NSObject instance variables there may be
// whatever NSResponder instance variables there may be
};
Thus, NSResponder* can always be treated as an NSObject*, and both of
them can be treated as a struct objc_object. NOTE: I just used the
class names to name these example structs, in reality, the compiler
won't accept that. I think it's worth mentioning that GTK is a toolkit
which does this as well, except it has to do it by hand (similar to
what I've shown you above) as a C compiler has no concept of derived
classes.
A far better explanation of this will be found in the appendices of
Cocoa Programming by Anguish, Buck
and Yacktman (purple cover with sea anemone on the front). This is the
book to have if you are already familiar with GUI programming (in any
language/toolkit) and you know the C language (not necessary the C
library). I enjoyed reading the extremely well written and thorough
explanation of the Objective-C runtime. Oddly enough, I've never
actually had much need of delving that deeply in to the runtime, but it
makes me feel more comfortable knowing how it works rather than
treating it as a total black box. Perhaps you are simply looking for
that same comforting feeling of at least having some clue about how it
works.
Once you know that, just keep it in the back of your mind, because
you'll probably never really care about how it's done when doing normal
Cocoa programming.
:-D
-Dave
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.