8

I want to construct a simple Objective C program without Foundation. I tried:

#include <stdio.h>

@interface Foo{
    char * bar;
}
-(void)hello;
@end

@implementation Foo
-(void)hello {
    printf("Hello world!");
}
@end

int main(){
    Foo * foo = [Foo alloc];
    return 0;
}

Then it tells me Foo may not respond to +alloc and autorelease called without pool...

How can I initialize an object without using alloc from Foundation?

LuisABOL
  • 2,951
  • 4
  • 25
  • 57
SwiftMango
  • 15,092
  • 13
  • 71
  • 136

3 Answers3

9

It's very simple to create a new object without using alloc from Foundation. The Objective-C runtime library itself provides functions that allow one to allocate objects from classes and deallocate them later, so that you need no extra library to create and destruct objects.

The function id class_createInstance(Class cls, size_t extraBytes) receives a class object, from which to allocate a new object, and an integer, which is almost always zero, and returns a new instance of cls.

Similarly, the function id object_dispose(id obj) takes an Objective-C object, calls the C++ destructor of every C++ object instance variable, removes existing associated references and frees it.

class_createInstance and object_dispose are both declared in /usr/include/objc/runtime.h.

So, you can implement your own +alloc and -dealloc methods. Your program would look like this:

#include <stdio.h>
#include <objc/runtime.h>

@interface Foo{
    char * bar;
}
+(id)alloc;
-(void)hello;
@end

@implementation Foo
+(id)alloc {
    // Returns a new 'Foo' object. In this case, 'self' is a 'Foo' class object,
    // whose type is 'Class', as required by `class_createInstance`.
    return class_createInstance(self, 0);
}
-(void)dealloc {
    object_dispose(self);
}
-(void)hello {
    printf("Hello world!");
}
@end

int main(){
    Foo *foo = [Foo alloc];
    [foo hello];
    [foo dealloc];

    return 0;
}

Compile it as you normally do:

gcc Foo.m -o Foo -lobjc

That's all!

LuisABOL
  • 2,951
  • 4
  • 25
  • 57
  • I looked into the runtime.h, and found: to destroy an object, use `object_dispose(obj)` in case anyone asks. – SwiftMango Mar 25 '13 at 02:21
  • Well remembered, @texasbruce. – LuisABOL Mar 25 '13 at 16:49
  • It is noteworthy that no part of Objective-C actually requires you to use class_createInstance and object_dispose, but it is probably a good idea unless you have a reason not to. You can create an Objective-C object with malloc, C++'s new operator, and in global variables and the stack if you know the size at compile time. All you need is to set the isa pointer correctly, which class_createInstance does for you apart from allocating memory, and then call init or, if you are really feeling adventurous, initialize the Ivars yourself. – DexterHaxxor Sep 17 '22 at 11:23
1

You can write Objective C without Foundation, but of course you may end up re-inventing the wheel to some degree.

As millimoose suggests, you could use the GNUStep Objective C runtime.

For more info, see:

Community
  • 1
  • 1
occulus
  • 16,959
  • 6
  • 53
  • 76
  • I tried the first one with `Object.h` but it still tells me the alloc method is not defined... I guess I have to use NSObject then – SwiftMango Mar 23 '13 at 23:23
0

You don't define alloc, because you don't inherit from NSObject which is part of foundation.

Here the cases are two:

  1. You think that foundation is evil, or for some reason you can't use it.
  2. You're doing it for exercise.

If you aren't in the second case, and neither in some particular case which makes foundation impossible to use, I would reconsider your choice.

However if you don't want to use foundation, alloc should return an object with the isa pointer initialized.

Ramy Al Zuhouri
  • 21,580
  • 26
  • 105
  • 187
  • Also make sure you have taken care of tag pointer and small objects for your custom allocation. It's better to use what your runtime gives you. It isn't necessary that objects must expose or have an isa. – Fred Frith-MacDonald Mar 26 '13 at 22:08