【问题标题】:objective c undefined symbol compilation error目标c未定义符号编译错误
【发布时间】:2011-06-03 18:49:06
【问题描述】:

请帮忙!我在目标 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.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;
}

编译器调用:

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

【问题讨论】:

  • -framework Foundation 添加到您的 gcc 命令行中。

标签: objective-c compiler-errors


【解决方案1】:

在你的命令行上:

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 并创建一个新项目:文件 > 新建 > 新项目;

  2. 选择适合您的项目类型(适合使用命令行工具);

  3. 将 SimpleCar.c/h 和 CarApp.c 添加到您的项目中;删除旧的 main.c;

    (4. 如果您选择命令行工具以外的项目类型,而不是将 CarApp.c 添加到项目中,您应该将 main() 函数的内容复制到 ApplicationDelegate 中的 -awakeFromNib 函数中。 )

【讨论】:

  • 你可能是对的。在他们用 xcode 编译的教程中,尽管它不想让我选择这样做。你能告诉我为什么我不能编译/如何在 xcode 中编译,或者我的命令行调用应该是什么样子。谢谢
  • “它不想给我选择”是什么意思?它必须工作...... :-)
  • 我将尝试显示屏幕截图,我从未真正使用过 xcode 进行编译,但学习如何编译会很好,只需一秒钟
  • 我的建议:暂时忘记教程。为应用程序创建一个新的 Xcode 项目并运行它(它应该可以编译并且一切正常)。然后,如果可行,您可以尝试将代码移动到新项目(注意正确设置应用程序委托)。
【解决方案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

【讨论】:

    猜你喜欢
    • 2013-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-15
    • 2017-03-03
    相关资源
    最近更新 更多