Reputation: 8148
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;
}
Upvotes: 3
Views: 2266
Reputation: 1848
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.
Upvotes: 0
Reputation: 488
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.
Upvotes: 0
Reputation: 162722
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.
Upvotes: 18
Reputation: 789
Import Foundation.
#import <Foundation/Foundation.h>
Extend NSObject instead of Object.
@interface Greeter : NSObject
Upvotes: 2
Reputation: 95405
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>
Upvotes: 3