цель c ошибка компиляции неопределенного символа

Помоги пожалуйста! моя первая программа в объективе c. Следовал учебнику слово в слово, но это дает мне эту ошибку, которую я не знаю, как читать для цели c.

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.м:

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

вызов компилятора:

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

ошибка:

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

person Andrew    schedule 03.06.2011    source источник
comment
Добавьте -framework Foundation в командную строку gcc.   -  person Darren    schedule 03.06.2011


Ответы (2)


Похоже, вы только что создали рабочее пространство Xcode без проекта Xcode. Вот проект, который вы могли бы использовать:

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

Как правило, вы просто выбираете «Файл»> «Новый проект», чтобы создать новый проект. Вероятно, для этого конкретного проекта вам понадобится программа командной строки на базе Foundation.

К сожалению, учебник не дал наилучшей реализации класса SimpleCar. Ниже приведен один из возможных вариантов перезаписи:

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

Закомментированный код выше является исходным кодом. Это потенциально опасно, а также приводит к утечке памяти. Первая строка исходного кода освобождает vin, прежде чем делать что-либо еще, что потенциально опасно. Например, что, если в вашем CarApp.m вы сделали это:

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

Исходный код освободил бы существующее значение vin, не заботясь о том, чтобы передаваемое значение не было на самом деле самим vin. Установив vin = newVin, он установил vin так, чтобы он указывал на себя, но после того, как был отпущен. Любые последующие попытки отправить сообщения на vin приведут к сбою или непредсказуемым результатам.

В исходном коде также происходит утечка памяти. Экземпляры NSNumber неизменяемы, поэтому создание числа через alloc/init на самом деле не имеет особого смысла (поскольку оно всегда будет равно нулю и никогда не может быть изменено). Мой код замены сначала сохраняет переданное значение на случай, если оно окажется vin. Затем он освобождает vin, а затем назначает vin newVin.

Методы setMake: и setModel: проблематичны по тем же причинам.

- (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
person NSGod    schedule 04.06.2011

В вашей командной строке:

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

вы не включаете необходимые рамки для Cocoa и других.

Я предлагаю создать ваше приложение с помощью Xcode, а не командной строки.

Если вы хотите попробовать из командной строки, добавьте все используемые вами фреймворки с помощью переключателя компоновщика -framework, например:

-framework Cocoa

но тогда вам также понадобится другой переключатель, идентифицирующий SDK, с которым вы строите (я полагаю), например:

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

РЕДАКТИРОВАТЬ: если вы хотите и пытаетесь использовать Xcode 4 для создания своего проекта, выполните следующие действия:

  1. откройте Xcode и создайте новый проект: File › New › New Project;

  2. выберите подходящий вам тип проекта (подойдет инструмент командной строки);

  3. добавьте в свой проект SimpleCar.c/h и CarApp.c; удалить старый main.c;

    (4. Если вы выберете тип проекта, отличный от инструмента командной строки, вместо добавления CarApp.c в проект вам следует скопировать содержимое вашей функции main() в функцию -awakeFromNib, найденную в вашем ApplicationDelegate.)

person sergio    schedule 03.06.2011
comment
наверное ты прав. в учебнике, который они скомпилировали в xcode, хотя он не хочет давать мне возможность сделать это. Не могли бы вы посоветовать мне, почему я не могу скомпилировать / как скомпилировать в xcode или как должен выглядеть мой вызов командной строки. Благодарность - person Andrew; 03.06.2011
comment
Что значит не хочет давать мне вариант? Должно работать... :-) - person sergio; 03.06.2011
comment
я постараюсь показать скриншот, я никогда не использовал xcode для компиляции, но было бы неплохо узнать, как это сделать, секундочку - person Andrew; 03.06.2011
comment
скриншот: docs.google.com/document/d/ - person Andrew; 03.06.2011
comment
Мое предложение: забудьте учебник на мгновение. Создайте новый проект Xcode для приложения и запустите его (он должен скомпилироваться, и все будет в порядке). Затем, если это сработает, вы можете попытаться переместить свой код в новый проект (заботясь о правильной настройке делегата приложения). - person sergio; 03.06.2011
comment
так что теперь он работает в xcode, но я получаю сообщение об ошибке: Thread1: программа получила сигнал EXC_BAD_ACCESS - person Andrew; 04.06.2011
comment
Пожалуйста, смотрите мое редактирование для получения более подробных инструкций о проекте. Если проблема не устранена, запустите программу в режиме отладки, чтобы при сбое вы точно видели, где именно. - person sergio; 04.06.2011
comment
Ты обалденный! IDK, почему было так чертовски сложно понять, как скомпилировать программу Ojbective C без Xcode, но это помогло (для всех после меня: gcc hello-world.m -framework Foundation) - person Joshua Cheek; 05.08.2014