2013-03-23 12 views
6

Voglio costruire un semplice programma Objective C senza Foundation. Ho provato:Come allocare un nuovo oggetto senza Foundation?

#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; 
} 

Poi mi dice Foo may not respond to +alloc e autorelease called without pool ...

Come posso inizializzare un oggetto senza utilizzare alloc da Fondazione?

+2

Perché si desidera evitare l'utilizzo di Foundation? – occulus

+0

@occulus Perché voglio utilizzare l'Objective C come alternativa a C++ e non sto eseguendo Mac OS – texasbruce

+2

@texasbruce Quindi utilizzare il runtime di GNUStep. (Non è esattamente una scelta pratica di piattaforma, ma funzionerebbe meglio di provare a reinventare 'NSObject'.) – millimoose

risposta

9

È molto semplice creare un nuovo oggetto senza utilizzare alloc da Foundation. La libreria runtime Objective-C fornisce di per sé funzioni che consentono di allocare oggetti da classi e deallocarli in seguito, in modo da non aver bisogno di librerie aggiuntive per creare e distruggere oggetti.

La funzione id class_createInstance(Class cls, size_t extraBytes) riceve un oggetto di classe, da cui allocare un nuovo oggetto e un numero intero, che è quasi sempre zero, e restituisce una nuova istanza di cls.

Analogamente, la funzione id object_dispose(id obj) accetta un oggetto Objective-C, chiama il distruttore C++ di ogni variabile di istanza dell'oggetto C++, rimuove i riferimenti associati esistenti e lo libera.

class_createInstance e object_dispose sono entrambi dichiarati in /usr/include/objc/runtime.h.

Quindi, è possibile implementare i propri metodi +alloc e -dealloc.Il tuo programma sarà simile a questa:

#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; 
} 

compilarlo come si fa normalmente:

gcc Foo.m -o Foo -lobjc 

Questo è tutto!

+0

Ho esaminato il runtime.h e ho trovato: per distruggere un oggetto, utilizzare 'object_dispose (obj)' nel caso qualcuno lo chieda. – texasbruce

+0

Ben ricordato, @texasbruce. – LuisABOL

1

È possibile scrivere l'obiettivo C senza fondotinta, ma naturalmente si rischia di reinventare la ruota in una certa misura.

Come suggerisce il millimoose, è possibile utilizzare lo GNUStep Objective C runtime.

Per maggiori informazioni, si veda:

+0

Ho provato il primo con 'Object.h' ma mi dice ancora che il metodo di allocazione non è definito ... Suppongo di dover usare NSObject quindi – texasbruce

0

non si definisce alloc, perché non si eredita da NSObject che è parte della fondazione.

Qui i casi sono due:

  1. Voi pensate che fondazione è il male, o per qualche motivo non è possibile utilizzarlo.
  2. Lo stai facendo per l'esercizio.

Se non si è nel secondo caso e in un caso particolare che rende impossibile l'utilizzo delle basi, riconsidererei la scelta.

Tuttavia, se non si desidera utilizzare la base, alloc deve restituire un oggetto con il puntatore isa inizializzato.

+0

Assicurati anche di aver preso cura del puntatore del tag e degli oggetti piccoli per il tuo allocazione personalizzata. È meglio usare ciò che il runtime ti dà. Non è necessario che gli oggetti debbano esporre o avere un isa. –

Problemi correlati