Simple self contained Objective C file - objective-c

I'm trying to run through all the Objective C I possibly can as fast as I can for my new job. I've divided up my training so I do 1/2 with cocoa tutorials and I thought it also made sense to try to learn Objective C from a general perspective as well so the other 50% i'm trying to learn out of the "Programming In Objective C" book by Stephan Kochan (2004). Many of his examples up through the first 50 pages or so seem to imply that there is a way to make a simple class (interface, implementation, and main) all in the same file. I have been trying to compile this in the mac Snowleopard terminal for the sake of speed, but as soon as I call a method inside the main I get compile errors.
I know its not my gcc compiler because the file will compile, and I can even write a printf statement, but as soon as I try to call a method, I get compile errors. I would appreciate it if someone could demonstrate a simple inclusive objectivec.m file that actually works with a method call.
here's my code
#import <stdio.h>
#import <objc/Object.h>
#interface testing1 : Object
{
int number;
}
-(void) setNum:(int)a;
-(void) print;
#end
#implementation testing1;
-(void) setNum:(int) a{
number = a;
}
-(void) print{
printf("this is the number %i \n", number);
}
#end
int main(int argc, char* argv[] )
{
//testing1 *test =[testing1 new];
//[test setNum: (int)34];
printf("testing");
//[test print];
}
this will compile in the terminal with --- gcc tester1 -o myProg -l objc
I've tried to call those methods several different ways but it does not work
any help is appreciated. Perhaps I need to break it up and use make - I don't know
Thanks
MIke

You have ; at the end of #implementation -
#implementation testing1; // Semi colon shouldn't be present at the end
With that modification made, you should see the result. Online result of the program
[test setNum: (int)34];
Here typecasting 34 to int is unnecessary. You can just pass the message setNum to reference test with 34 followed by colon.
[test setNum:34 ];
Interface declarations should go in header while the implementation to source files. Only source files get compiled. Before even the compilation phase, pre-processor just copies the content of all imported files to the translation units. So,
testing.h
#import <Foundation/NSObject.h>
#interface testing1 : NSObject
{
int number;
}
-(void) setNum:(int)a;
-(void) print;
#end
testing.m
#import <stdio.h>
#import "testing.h"
// You should definitely import just stdio.h header here because of printf function usage
// testing.h also to be imported or else compiler doesn't know what is testing1.
#implementation testing1
-(void) setNum:(int) a{
number = a;
}
-(void) print{
printf("this is the number %i \n", number);
}
#end
main.m
#import <stdio.h>
#import "testing.h"
int main(int argc, char* argv[] )
{
testing1 *test =[testing1 new];
[test setNum: 34];
printf("testing");
[test print];
return 0;
}
Now you need to compile the two source files from which corresponding object files are generated. Linker combines these object files to give the final executable.
gcc -o test testing.m main.m -framework Foundation
Run -
./test

The book you're following is out of date. The Object class was effectively deprecated way back in 1994 with the introduction of OpenStep.
In Objective-C 2.0, the Object class simply isn't available at all. That's why your program produces compiler warnings/errors.
You should instead subclass NSObject and import <Foundation/Foundation.h>. Use the -framework Foundation gcc parameter, instead of -l objc.

First of all, you used #import <stdio.h>. You only need that when your using C only. Delete the sentence and use this instead.
#import <Foundation/Foundation.h>
Secondly, why are you using #import <objc/Object.h>? The "<" and ">" are only for frameworks. If you want to import another file you made, use #import "Object.h" instead. (Unless you're talking about NSObject, then you don't need to import anything because it is part of the Foundation framework.)
And lastly, you should take away the semicolon after the #implementation because it's unnecessary.

Related

Can an Objective-C implementation be defined in a header file and also be imported by multiple source files?

I am aware this is not standard or conventional, please read on. I have a header file that defines the interface and implementation of an Objective-C class.
Person.h
#ifndef Person_h
#define Person_h
#interface Person : NSObject
-(void)speak;
#end
#implementation Person
-(void)speak
{
// Say something
}
#end
#endif /* Person_h */
I also have two source files that both include the header file.
Main.mm
#import Foundation;
#import "Person.h"
int main(int argc, const char * argv[])
{
// Do nothing
}
Test.mm
#import Foundation;
#import "Person.h"
When the project is built, I get duplicate symbol errors.
duplicate symbol '_OBJC_CLASS_$_Person' in:
/Debug/TestBox.build/Objects-normal/x86_64/main.o
/Debug/TestBox.build/Objects-normal/x86_64/test.o
duplicate symbol '_OBJC_METACLASS_$_Person' in:
/Debug/TestBox.build/Objects-normal/x86_64/main.o
/Debug/TestBox.build/Objects-normal/x86_64/test.o
ld: 2 duplicate symbols for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I want to be able to include the same header file in multiple source files. In C++, I can inline the implementation into the header file like this:
#ifndef Person_h
#define Person_h
class Person
{
public:
void speak()
{
// Say something
}
};
#endif /* Person_h */
However, I haven't been able to find a way to do that with Objective-C. I'm using Objective-C so I can subclass events from NSWindowDelegate and NSResponder.
I tried searching for solutions. Most of them said to separate the implementation into a source file, but that would break the single-header architecture. One suggestion is to use the Objective-C runtime library and create my classes at runtime. This appears to give me the results I'm looking for, but I'm wondering if there is a simpler way.
Is there some way to implement an Objective-C class in a header file so it can be included by multiple source files? Or is dynamically creating the classes at runtime my best option?
Update
I am looking for a solution that avoids using a .m or .mm file to write the Objective-C implementation. Even if doing so is not the conventional way to do it. The single-header file is required by the architecture of the project I am working on. The project is cross-platform, and the single-header design isn't an issue in C++ on Windows and Linux. Adding a source file to define Objective-C objects would break the existing architecture.
Thats not purpose of header file. In header file you will define properties and methods which you want to make available where needed.
Implementation always lies within .m file in case of Objective C.
EDIT
Sure thing, of course you can ... I've removed the previous failed attempt to remove clutter.
// main.m
#import <Foundation/Foundation.h>
#import "A.h"
#import "B.h"
#import "C.h"
int main(int argc, const char * argv[])
{
#autoreleasepool
{
NSLog(#"Hello, World!");
[[A alloc] init];
[[B alloc] init];
[[C alloc] init];
}
return 0;
}
// A.h, repeat for B.h and C.h
#import <Foundation/Foundation.h>
#interface A : NSObject
#end
// A.m
// B.m and C.m are quite similar
// BUT drop the line below from B and C
#define ZIMP
#import "A.h"
#import "Header.h"
#implementation A
- ( id ) init
{
self = super.init;
[[[Z alloc] init] msg:#"A"];
return self;
}
#end
Now for the grand finale
// Header.h
#import <Foundation/Foundation.h>
#interface Z : NSObject
- ( void ) msg:( NSString * ) src;
#end
#ifdef ZIMP
#implementation Z
- ( void ) msg:( NSString * ) src
{
NSLog( #"%# says hi", src );
}
#end
#endif
The proof of the pudding ... here is the output
2020-07-15 07:29:52.134413+0200 HdrImp[26901:700649] Hello, World!
2020-07-15 07:29:52.135121+0200 HdrImp[26901:700649] A says hi
2020-07-15 07:29:52.135297+0200 HdrImp[26901:700649] B says hi
2020-07-15 07:29:52.135389+0200 HdrImp[26901:700649] C says hi
Program ended with exit code: 0
The trick is of course to get the compiler to see the implementation only once, even though the header file is included several times. This is accomplished with nothing but a single #define.
Now we can tell the Swift guys that Objective-C can be done with just a single source file.
UPDATE
This works because I know precisely which files will be included and I can set the guard in one of them. If you do not know beforehand which of the files will be part of the compile you have a problem but you can solve that with more defines and by some code in your make file where you 'know' which of the files will be included and can take action based on that.
You need to understand the different purposes of header (.h) and module (.m) files:
The correct usage is this:
A Header file just declares the types and what they are composed of. It is like saying to the compiler: Look, somewhere is a class named Person, and you can call speak on it. It does not tell the compiler the internals of the speak function, it just announces that this type exists somewhere.
This is called a type declaration.
When the compiler translates the Main.mm file, it creates a call to a yet-unknown, external function speak. It does the same for Test.mm.
Then, after compilation of your code, the linker runs to resolve all the unknown addresses, e.g. it checks if there is one and exactly one definition of a class Personwith a function speak. If there is no such definition, you get an unresolved symbol error. If there are multiple definitions, you get your duplicate symbol error.
Therefore, you need to create a Module file to define all your classes - exactly once. In your case you need a file Person.m, which contains the #implementation of the class (and functions).
Types can be declared multiple times, but may only be defined once.
What you did wrong: When you put your type definition into the header file, the compiler creates two implementations of your class (when translating Main.mm and the other when translating Test.mm), which then confuses the linker, because the linker expects exactly one.
You can have a central header file which aggregates all types and sub-includes, but you need one (or more) separate module files - and you must not include them, because the linker resolves the references for you.

Objective C compilation with gcc 4.6.2

I am trying to learn objective c on windows. My program compiles with warnings
My code is
#include <objc/Object.h>
#interface Greeter:Object
{
/* This is left empty on purpose:
** Normally instance variables would be declared here,
** but these are not used in our example.
*/
}
- (void)greet;
#end
#include <stdio.h>
#implementation Greeter
- (void)greet
{
printf("Hello, World!\n");
}
#end
#include <stdlib.h>
int main(void)
{
id myGreeter;
myGreeter=[[Greeter alloc] init];
[myGreeter greet];
[myGreeter release];
return EXIT_SUCCESS;
}
I compile my program on GNUStep using the following command
gcc -o Greeter Greeter.m -I /GNUstep/System/Library/Headers -L /GNUstep/System/Libra
/Libraries -lobjc -lgnustep-base -fconstant-string-class=NSConstantString
I get the following warnings on compilation
: 'Greeter' may not respond to '+alloc' [enabled by default]
: (Messages without a matching method signature [enabled by default]
: will be assumed to return 'id' and accept [enabled by default]
: '...' as arguments.) [enabled by default]
: no '-init' method found [enabled by default]
: no '-release' method found [enabled by default]
And so when I run my executable the object does not get instantiated.
I am using gcc from MinGW where gcc version is 4.6.2
--UPDATE---
The program runs fine when I extend from NSObject instead of Object
--UPDATE 2 ----
My Object.h looks like
#include <objc/runtime.h>
#interface Object
{
Class isa;
}
#end
--UPDATE 3 ----
I have modified my code as follows. It compiles fine, but I am not sure if this is the right way to go about things
#interface Greeter
{
/* This is left empty on purpose:
** Normally instance variables would be declared here,
** but these are not used in our example.
*/
}
- (void)greet;
+ (id)alloc;
- (id)init;
- release;
#end
#include <stdio.h>
#implementation Greeter
- (void)greet
{
printf("Hello, World!\n");
}
+ (id)alloc
{
printf("Object created");
return self;
}
- (id)init
{
printf("Object instantiated");
return self;
}
- release {}
#end
#include <stdlib.h>
int main(void)
{
id myGreeter;
myGreeter=[[Greeter alloc] init];
[myGreeter greet];
[myGreeter release];
return EXIT_SUCCESS;
}
Unless you are studying the history of Objective-C, trying to learn the language based on the Object class is a complete waste of time. The Object class was last used commonly as a root class in pre-1994 NEXTSTEP.
If your goal is to learn pre-1994 Objective-C, then state that because, if so, the answers you have so far are entirely wrong. Even if the goal is to go with modern patterns, the answers are more along the lines of How do I recreate NSObject? than anything else. Note that if that is your goal.... well... go for it! Pre-1994 Objective-C was kinda like OOP macro-assembly and, through that, there was a ton of power through at the metal simplicity.
For example, you say that "I have modified my code as follows. It compiles fine, but I am not sure if this is the right way to go about things".
That code compiles, but -- no -- it doesn't work. Not at all. For starters, the +alloc method doesn't actually allocate anything. Nor does the Greeter class implement near enough functionality to act anything like an NSObject.
If your goal is to learn something akin to modern Objective-C and use Windows to do so, the best possible way would likely to be to install the GNUStep toolchain. With that, at least, you would be programming against an NSObject rooted set of APIs akin to modern Cocoa (and, to a lesser extent, iOS).
If your goal is to learn truly modern Objective-C, you'll want an environment that can run the latest versions of LLVM, at the very least. And, of course, if you want to write Objective-C based iOS or Mac OS X apps, you'll want a Mac running Lion.
From memory, the Object class does not implement retain counts, so it wouldn't have release, it'll have free or some other method. It should have +alloc and -init though. Since there's no “Objective-C standard”, you'll have to open up your objc/Object.h and see exactly what it offers.
Note that on GCC 4.6.2, objc/Object.h actually includes objc/deprecated/Object.h, meaning support for Object as a class may be fairly limited. If it doesn't include it, try including it yourself:
#import <objc/deprecated/Object.h>
Import Foundation.
#import <Foundation/Foundation.h>
Extend NSObject instead of Object.
#interface Greeter : NSObject
What I did was to install gcc-4.6 alongside the 4.7 that came with the linux system.
It seems to work, as it has a compatability layer for older code.
In my basic Makefile I specify
> CC=gcc-4.6
> LIBS=-lobjc -lpthread
>
> all: objc-test.m
> $(CC) -o objctest objc-test.m $(LIBS)
There is nothing "wrong" with using and older version of gcc.
The new 4.7 version has gutted
the objc system so it is not a stand-alone compilation suite. That sucks. I imagine there is some reason, possibly a political one, possibly just that it is difficult to make one compiler do it all for everyone. I have successfully made objc programs with gnustep in X86_64 Linux with gcc 4.7.3 after banging out failure for two days the old way.
It involves a bunch of setup:
setting up the environment variables with
source /usr/share/GNUstep/Makefiles/GNUstep.sh
and conforming to their build system.
A Basic GNUmakefile:
include $(GNUSTEP_MAKEFILES)/common.make
TOOL_NAME = test
test_OBJC_FILES = main.m
include $(GNUSTEP_MAKEFILES)/tool.make
for
main.m:
#import <Foundation/Foundation.h>
int
main (void)
{
NSLog (#"Executing");
return 0;
}
running
gs_make
builds the binary in a subdir obj.
It is actually quite frustrating to fight with the build system like that
and have to spend hours teasing out tidbitsfrom docs just to get basic functionality
from such a great compiler. I hope they fix it in coming iterations.
Have you tried with [Greeter new]; ? Open Object.h and take a look at the methods defined in the Object class...
EDIT:
To implement the alloc, retain and release you have to call the objc runtime.
So.. I think you have to write something like this:
#interface RootObject : Object
+ (id)alloc;
- (id)init;
- (id)retain;
- (void)release;
#end
#implementation RootObject
{
unsigned int retainCount;
}
+ (id)alloc
{
id myObj = class_createInstance([self class], 0);
/* FOR NEWBIES this works for GCC (default ubuntu 20.04 LTS)
id myObj = class_createInstance(self, 0);
*/
return myObj;
}
- (id)init
{
retainCount = 1;
return self;
}
- (id)retain
{
retainCount++;
return self;
}
- (void)release
{
retainCount--;
if (retainCount == 0) {
object_dispose(self);
}
}
#end
And then you can subclass RootObject.

objective c gnustep - cannot separate interface and implementation files

I am using gnustep for objective-c on windows. If i keep interface and implementation files of a class together with main file, it compiles without error and gives expected output.
Following is the example:
// File "classA.h"
#import <Foundation/Foundation.h>
#interface classA: NSObject
{
int a;
}
-(void) print;
#end
// File "classA.m"
#import "classA.h"
#implementation classA
-(void) print
{
a = 10;
NSLog(#"a = %i", a);
}
#end
// File "test.m"
#import "classA.h"
int main(int argc, char *argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSLog(#"start");
classA *objA = [[classA alloc] init];
[objA print];
[objA release];
NSLog(#"done");
[pool drain];
return 0;
}
However, if i put the interface and implementation files separately, on compiling using following command
gcc `gnustep-config --objc-flags` -o program program.m -L /GNUstep/System/Library/Libraries -lobjc -lgnustep-base
i get following error
undefined reference to `__objc_class_name_myNewClass'
collect2: ld returned 1 exit status
How do i keep the files separate and still compile the program successfully
Thanks for help
Regards
You have a linker error here. Most likely, you are not including a required header file for myNewClass.
I know this is old, but double check the name of compiled files just in case the error is in a different file.
Reasons:
The class myNewClass is not referenced in the code above and there are no other imports other than Foundation.
The name of the file in the code comments and the file you appear to be compiling differ.
// File "test.m"
gcc `gnustep-config --objc-flags` -o program program.m
By the look of it, the given code should compile when split out.
Also, about the question "Also how do i included "Compiled files"?", assuming you mean a .o file, you just need to include the header file (.h) and make sure the compiler can find the matching .o file. Related: How do I link object files in C? Fails with "Undefined symbols for architecture x86_64"

Write Objective-C class from scratch

I'd like to write an Objective-C class without Cocoa or GNU's Object.h (for educational purposes). I dug around the net and it seems to me that quite a lot of stuff that one would expect to "come with the language", such as classes and message sending are actually defined in files written by third parties, such as objc-runtime.h.
Is there any documentation about what is really pure Objective-C and what is part of the runtime / frameworks? And what functionality do I have to implement to get a working environment without using any third-party code such as Object.h or objc-runtime.h (note again that this is for educational purposes, not for production code)?
Thanks for any insight!
Really, the only thing you must take care of yourself if you don't inherit from NSObject is object creation and destruction; methods otherwise behave the same way regardless of their parent class. Features like KVC and memory management are features of OpenStep/Cocoa, but not required as part of the language.
Here's a class from scratch:
#interface MyClass { // note the lack of a superclass here
#private Class isa;
}
+ (MyClass *)create;
- (void)destroy;
- (int)randomNumber;
#end
#implementation MyClass
+ (MyClass *)create {
return class_createInstance(self, 0);
}
- (void)destroy {
object_dispose(self);
}
- (int)randomNumber {
return rand();
}
#end
And here's how it could be used:
int main(int argc, char **argv) {
MyClass *foo = [MyClass create];
if (foo) {
printf("random! %i\n", [foo randomNumber]);
[foo destroy];
}
}
Edit: If you don't even want to use class_createInstance() and object_dispose(), you'll have to implement equivalents manually, as well as an equivalent of class_getInstanceSize() so you know how much memory an object occupies. But even if you manage that, don't think you've escaped the Objective-C runtime! Message dispatch is still entirely built on the C functions in the runtime, and Objective-C syntax is transformed into calls to those functions during compilation.
Matt Gallagher wrote a really cool post on writing a bare-bones Cocoa program. Since Objective-C is a superset of C, you can just do:
echo "int main(){return 0;}" | gcc -x objective-c -; ./a.out ; echo $?
Anyways, you probably would get a lot out of reading his post.
As far as avoiding the framework and creating your own base object goes, all you need to do is make sure that the first iVar is declared Class is_a and you could probably have a reasonable stab at replicating NSObject is by passing through to the runtime functions.
As far as avoiding the runtime library AND the framework goes, that's not really possible. Objective C (or at least, the bits that aren't just C) is a dynamic language. So pretty much everything it does that C doesn't do is handled by the runtime library.
It might be possible to build your own classes and objects using the 32bit runtime and the deprecated API, which doesn't abstract away the layout of classes, protocols, etc. to the extent that the modern runtime does (I've only really poked around with the modern runtime)
Perhaps you could create classes, add methods and allocate instances and by setting values in class_t structs and then using malloc() to allocate, although even then, you'd still be implicitly using the runtime function objc_msgSend every time you used the [obj selector] syntax -- unless you want to implement that as well, in which case you've just reimplemented the language yourself. The 'pure core' of the language you're looking for just is the runtime.
Here's an example of class, without using class_createInstance or object_dispose, or any other Objective-C Runtime (at least we don't call them directly).
#import <objc/objc.h>
#import <stdio.h>
#import <stdlib.h>
#import <string.h>
static Class __scratchClass = NULL;
#interface Scratch {
Class isa;
char *name;
}
+ (id) initialize;
+ (Scratch*) new:(const char*)strName;
- (void) sayHello;
- (void) destroy;
#end
#implementation Scratch
+ (id) initialize {
__scratchClass = self;
return self;
}
+ (Scratch*) new:(const char*) strName {
Scratch* pObj = (Scratch*)malloc(sizeof(Scratch));
if (!pObj) return NULL;
memset(pObj, 0, sizeof(Scratch));
pObj->isa = __scratchClass;
pObj->name = (char*)malloc(strlen(strName)+1);
strcpy(pObj->name, strName);
return pObj;
}
- (void) sayHello {
printf("Hello, World!\nThis is Scratch (%s)...\n", name);
}
- (void) destroy {
if (name) {
free(name);
name = NULL;
}
free(self);
}
#end
int main(int argc, char** argv) {
Scratch* ps = [Scratch new:argv[0]];
[ps sayHello];
[ps destroy];
return 0;
}
Compile the code with (assuming you save it as 'test1.m'):
gcc -o test1 test1.m -lobjc

Concise description of how .h and .m files interact in objective c?

I have just started learning objective C and am really confused how the .h and .m files interact with each other. This simple program has 3 files:
Fraction.h
#import <Foundation/NSObject.h>
#interface Fraction : NSObject {
int numerator;
int denominator;
}
- (void) print;
- (void) setNumerator: (int) n;
- (void) setDenominator: (int) d;
- (int) numerator;
- (int) denominator;
#end
Fraction.m
#import "Fraction.h"
#import <stdio.h>
#implementation Fraction
-(void) print { printf( "%i/%i", numerator, denominator ); }
-(void) setNumerator: (int) n { numerator = n; }
-(void) setDenominator: (int) d { denominator = d; }
-(int) denominator { return denominator; }
-(int) numerator { return numerator; }
#end
Main.m
#import <stdio.h>
#import "Fraction.h"
int main(int argc, char *argv[]) {
Fraction *frac = [[Fraction alloc] init];
[frac setNumerator: 1];
[frac setDenominator: 3];
printf( "The fraction is: " );
[frac print];
printf( "\n" );
[frac release];
return 0;
}
From what I understand, the program initially starts running the main.m file. I understand the basic C concepts but this whole "class" and "instance" stuff is really confusing. In the Fraction.h file the #interface is defining numerator and denominator as an integer, but what else is it doing below with the (void)? and what is the purpose of re-defining below? I am also quite confused as to what is happening with the (void) and (int) portions of the Fraction.m and how all of this is brought together in the main.m file. I guess what I am trying to say is that this seems like a fairly easy program to learn how the different portions work with each other - could anyone explain in non-tech jargon?
People who come from other environments always seem to belive that something complicated is happening with the .c, .m, and .h files used in C and Objective-C programming.
Actually, its very, VERY simple.
For the purpose of buiding a project Integrated Development Environments - like XCode - ignore all the .h files. What they do do is to take each .c and .m file and compile it. If the programmer (thats you) has used any #include, or #import directives, the compiler inserts the entire text of the included/imported .h file where the directive was.
So, if you had a .h file - insert.h - that said:
in
And a .c file that said:
Alice
#include "insert.h"
Wonderland
The compiler would, after processing the #include & #import directives, see this:
Alice
in
Wonderland
It is this very VERY simple file merging behavior that we use to make complicated programs :)
.h is very simply a convention by which programmers can tell each other that the file is suitable to be merged in - potentially multiple times - using #include or #import.
The .c and .m files are not merged like that. Each .c and .m file is compiled seperately - to produce .o files. Each .o file is a collection of compiled functions. The .o files are then merged - or "linked" - to produce the final program.
The linking step ensures that each function exists only once, and that all functions that are called do in fact exist somewhere.
C & Objctive-C define one special function that must exist somewhere - main(). Again, the language is very relaxed - it doesn't care which .c or .m file the main() function is in. Merely that it exists in some file somewhere.
You need to take a look into Object Oriented Programming and perhaps read a little more into Objective-C development to get a good grasp on the concepts of OOP etc
To answer your question "what is the difference between .h and .m files", .h files contain the declaration for your class, so basically all of attributes and methods that it can utilise. The .m file is the implementation of these methods.
In laymans terms, the header file (.h) is the a way of saying "This is what I can do" and the .m is "This is how I do it". It's a little more complicated then that though.
The files don't interact at all, using them is merely a convention, you could also put everything in the main.m file.
A good starting point for learning Objective-C is the introduction to the Objective-C language.
In a nutshell, an Objective-C class is a C struct. An instance is a reference to such a struct that has been allocated in memory. A class has a name and an instance has a state or value.
The thing that sets an Objective-C class apart from a C struct is the ability to look up method addresses by name. In simplified terms, the struct has a hash table of function pointers keyed by name.
There are lots of other niceties in Objective-C objects, like reference counting, but calling methods by name is the crux of it. A SEL is a C string, but a C string is not a SEL.
As far as header and source files, by convention you declare the interface to a class in header files and define the methods in a source file. Defining things, other than types and constants, in a header file is a bad practice, as is including source files. You are free to declare anything you want in a source file, but it is essentially private to the source file.
A C executable, and thus an Objective-C executable, has an entry point at the main function. By convention main is defined in a file with the same name in Objective-C projects.
The below lines of code in Fraction.h are not nothing but getter methods. They are not redefining the two int variables declared above them.
- (int) numerator;
- (int) denominator;