2011-06-03 100 views
2

请帮忙!我的目标是第一个程序。遵循一个字的教程,但它给了我这个错误,我不知道如何阅读目标c。objective 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 
+9

将'-framework Foundation'添加到您的gcc命令行中。 – Darren 2011-06-03 19:02:38

回答

1

它看起来像你刚刚创建一个没有Xcode项目的Xcode工作区。下面是你可以使用一个项目:

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

一般情况下,你只需选择文件>新建项目来创建一个新的项目。您可能需要基于基础的命令行程序来执行此特定项目。

不幸的是,本教程没有给出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 
6

在你的命令行:

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

你不包括可可和其他所需的框架。

我的建议是使用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()函数的内容复制到ApplicationDelegate中的-awakeFromNib函数中。)

+0

你可能没错。在教程中他们编译在Xcode,但它不想让我选择这样做。 你既可以告诉我为什么我不能编译/如何在Xcode编译或我的命令行调用应该是什么样子。 谢谢 – Andrew 2011-06-03 19:03:08

+0

“它不想给我的选择”是什么意思?它必须工作... :-) – sergio 2011-06-03 19:04:38

+0

我会尝试并显示一个屏幕截图,我从来没有真正使用xcode编译,但它会很好学习如何,只需一秒 – Andrew 2011-06-03 19:06:48