2011-06-03 7 views
2

Aidez s'il vous plaît! mon premier programme en objectif c. Suivi un mot de tutoriel mot pour mot mais il me donne cette erreur que je ne sais pas tout à fait comment lire pour l'objectif c.objectif c undefined symbole erreur de compilation

SimpleCar.h:

#import <Cocoa/Cocoa.h> 


@interface SimpleCar : NSObject { 
    NSString* make; 
    NSString* model; 
    NSNumber* vin; 
} 

// set methods 
- (void) setVin: (NSNumber*)newVin; 
- (void) setMake: (NSString*)newMake; 
- (void) setModel: (NSString*)newModel; 

// convenience method 
- (void) setMake: (NSString*)newMake 
     andModel: (NSString*)newModel; 

// get methods 
- (NSString*) make; 
- (NSString*) model; 
- (NSNumber*) vin; 

@end 

SimpleCar.m:

#import "SimpleCar.h" 


@implementation SimpleCar 
// set methods 
- (void) setVin: (NSNumber*)newVin { 

    [vin release]; 
    vin = [[NSNumber alloc] init]; 
    vin = newVin; 

} 

- (void) setMake: (NSString*)newMake { 

    [make release]; 
    make = [[NSString alloc] initWithString:newMake]; 

} 

- (void) setModel: (NSString*)newModel { 

    [model release]; 
    model = [[NSString alloc] initWithString:newModel]; 

} 

// convenience method 
- (void) setMake: (NSString*)newMake 
     andModel: (NSString*)newModel { 

    // Reuse our methods from earlier 
    [self setMake:newMake]; 
    [self setModel:newModel]; 

} 

- (NSString*) make { 
    return make; 
} 

- (NSString*) model { 
    return model; 
} 

- (NSNumber*) vin { 
    return vin; 
} 

-(void) dealloc 
{ 
    [vin release]; 
    [make release]; 
    [model release]; 
    [super dealloc]; 
} 

@end 

CarApp.m:

#import <Foundation/Foundation.h> 
#import "SimpleCar.h" 

int main (int argc, const char * argv[]) { 

    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 

    SimpleCar *myCar = [[SimpleCar alloc] init]; 

    NSNumber *newVin = [NSNumber numberWithInt:123]; 

    [myCar setVin:newVin]; 
    [myCar setMake:@"Honda" andModel:@"Civic"]; 

    NSLog(@"The car is: %@ %@", [myCar make], [myCar model]); 
    NSLog(@"The vin is: %@", [myCar vin]); 

    [myCar release]; 

    [pool drain]; 

    return 0; 
} 

appel compilateur:

bash-3.2$ gcc CarApp.m SimpleCar.m -g -m64 

erreur:

Undefined symbols for architecture x86_64: 
    "___CFConstantStringClassReference", referenced from: 
     CFString in ccR0Zlgm.o 
     CFString in ccR0Zlgm.o 
     CFString in ccR0Zlgm.o 
     CFString in ccR0Zlgm.o 
    "_objc_msgSend", referenced from: 
     _main in ccR0Zlgm.o 
     -[SimpleCar setVin:] in ccJfVliU.o 
     -[SimpleCar setMake:] in ccJfVliU.o 
     -[SimpleCar setModel:] in ccJfVliU.o 
     -[SimpleCar setMake:andModel:] in ccJfVliU.o 
    (maybe you meant: l_objc_msgSend_fixup_release, l_objc_msgSend_fixup_alloc) 
    "_NSLog", referenced from: 
     _main in ccR0Zlgm.o 
    "_objc_msgSend_fixup", referenced from: 
     l_objc_msgSend_fixup_alloc in ccR0Zlgm.o 
     l_objc_msgSend_fixup_release in ccR0Zlgm.o 
     l_objc_msgSend_fixup_release in ccJfVliU.o 
     l_objc_msgSend_fixup_alloc in ccJfVliU.o 
    (maybe you meant: l_objc_msgSend_fixup_release, l_objc_msgSend_fixup_alloc) 
    "_OBJC_CLASS_$_NSAutoreleasePool", referenced from: 
     objc-class-ref in ccR0Zlgm.o 
    "_OBJC_CLASS_$_NSNumber", referenced from: 
     objc-class-ref in ccR0Zlgm.o 
     objc-class-ref in ccJfVliU.o 
    "_objc_msgSendSuper2", referenced from: 
     -[SimpleCar dealloc] in ccJfVliU.o 
    "_OBJC_METACLASS_$_NSObject", referenced from: 
     _OBJC_METACLASS_$_SimpleCar in ccJfVliU.o 
    "__objc_empty_cache", referenced from: 
     _OBJC_METACLASS_$_SimpleCar in ccJfVliU.o 
     _OBJC_CLASS_$_SimpleCar in ccJfVliU.o 
    "__objc_empty_vtable", referenced from: 
     _OBJC_METACLASS_$_SimpleCar in ccJfVliU.o 
     _OBJC_CLASS_$_SimpleCar in ccJfVliU.o 
    "_OBJC_CLASS_$_NSObject", referenced from: 
     _OBJC_CLASS_$_SimpleCar in ccJfVliU.o 
    "_OBJC_CLASS_$_NSString", referenced from: 
     objc-class-ref in ccJfVliU.o 
ld: symbol(s) not found for architecture x86_64 
collect2: ld returned 1 exit status 
+9

Ajoutez '-framework Foundation' à votre ligne de commande gcc. – Darren

Répondre

1

Il semble que vous venez de créer un espace de travail Xcode sans projet Xcode. Voici un projet que vous pouvez utiliser:

http://www.markdouma.com/developer/CarApp.zip

En général, vous choisissez simplement Fichier> Nouveau projet pour créer un nouveau projet. Vous voudrez probablement un programme de ligne de commande basé sur une fondation pour ce projet particulier.

Malheureusement, le tutoriel n'a pas donné la meilleure implémentation de la classe SimpleCar.Voici une réécriture possible:

#import "SimpleCar.h" 

@implementation SimpleCar 

-(void) dealloc 
{ 
    [vin release]; 
    [make release]; 
    [model release]; 
    [super dealloc]; 
} 


// set methods 
- (void) setVin: (NSNumber*)newVin { 
    [newVin retain]; 
    [vin release]; 
    vin = newVin; 
// [vin release]; 
// vin = [[NSNumber alloc] init]; 
// vin = newVin; 
} 

Le code commenté ci-dessus est le code original. Il est à la fois potentiellement dangereux et fuit la mémoire. La première ligne du code original publie vin avant de faire quoi que ce soit d'autre, ce qui est potentiellement dangereux. Par exemple, si dans votre CarApp.m vous avez fait ceci:

NSNumber *vinValue = [car vin]; 
[car setVin:vin]; 
NSLog(@"car's vin == %@", [car vin]); // unpredictable results/crash 

Le code original aurait libéré la valeur vin existante sans se soucier de vous assurer que la valeur transmise dans n'a pas été fait vin lui-même. En définissant vin = newVin, il était défini sur vin pour pointer vers lui-même mais après avoir été libéré. Toute tentative ultérieure d'envoyer des messages à vin entraînerait un plantage ou des résultats imprévisibles.

Le code d'origine fuit également la mémoire. Les instances de NSNumber sont immuables, donc créer un numéro par alloc/init n'a pas vraiment de sens (puisqu'il sera toujours zéro, et ne peut jamais être changé). Mon code de remplacement conserve d'abord la valeur transmise, au cas où il se trouve être vin. Il publie ensuite vin puis affecte vin à newVin. Les méthodes setMake: et setModel: sont problématiques pour les mêmes raisons.

- (void) setMake: (NSString*)newMake { 
    [newMake retain]; 
    [make release]; 
    make = newMake; 
// [make release]; 
// make = [[NSString alloc] initWithString:newMake]; 
} 

- (void) setModel: (NSString*)newModel { 
    [newModel retain]; 
    [model release]; 
    model = newModel; 
// [model release]; 
// model = [[NSString alloc] initWithString:newModel]; 
} 

// convenience method 
- (void) setMake: (NSString*)newMake 
     andModel: (NSString*)newModel { 
    // Reuse our methods from earlier 
    [self setMake:newMake]; 
    [self setModel:newModel]; 
} 

- (NSString*) make { 
    return make; 
} 
- (NSString*) model { 
    return model; 
} 
- (NSNumber*) vin { 
    return vin; 
} 
@end 
6

Sur la ligne de commande:

bash-3.2$ gcc CarApp.m SimpleCar.m -g -m64 

vous n'êtes pas compris les cadres nécessaires pour le cacao et d'autres.

Ma suggestion est la construction de votre application en utilisant Xcode, pas la ligne de commande.

Si vous voulez et essayez de la ligne de commande, ajoutez tous les cadres que vous utilisez à l'aide du commutateur de liaison -framework, par exemple:

-framework Cocoa 

, mais vous aurez également besoin d'un autre commutateur, identifiant le SDK vous bâtiment contre (je suppose), par exemple:

-isysroot /Developer/SDKs/MacOSX10.6.sdk 

EDIT: si vous voulez et essayez d'utiliser Xcode 4 pour construire votre projet, procédez comme suit:

  1. ouvrir Xcode et créer un nouveau projet: Fichier> Nouveau> Nouveau projet; Choisissez un type de projet qui vous convient (un outil de ligne de commande est approprié);

  2. Ajoutez SimpleCar.c/h et CarApp.c à votre projet; retirez l'ancien main.c; 4. Si vous choisissez un type de projet autre que l'outil de ligne de commande, au lieu d'ajouter CarApp.c au projet, vous devez copier le contenu de votre fonction main() dans la fonction -awakeFromNib de votre ApplicationDelegate.

+0

vous avez probablement raison. dans le tutoriel, ils ont compilé dans xcode, bien qu'il ne veuille pas me donner l'option de le faire. pourriez-vous soit me conseiller sur pourquoi je ne peux pas compiler/comment compiler dans xcode ou à quoi devrait ressembler mon appel en ligne de commande. merci – Andrew

+0

Que signifie "il ne veut pas me donner l'option"? Ça doit marcher ... :-) – sergio

+0

Je vais essayer de montrer une capture d'écran, je n'ai jamais vraiment utilisé xcode pour compiler mais ce serait bien d'apprendre comment, juste une seconde – Andrew