请帮忙!我在目标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
答案 0 :(得分:6)
在命令行上:
bash-3.2$ gcc CarApp.m SimpleCar.m -g -m64
您没有包含Cocoa和其他人所需的框架。
我的建议是使用Xcode构建应用程序,而不是命令行。
如果您想从命令行尝试并尝试使用-framework
链接器开关添加您正在使用的所有框架,例如:
-framework Cocoa
但是你还需要另一个开关,识别你正在构建的SDK(我想),例如:
-isysroot /Developer/SDKs/MacOSX10.6.sdk
编辑:如果您想要并尝试使用Xcode 4来构建项目,请按照以下步骤操作:
打开Xcode并创建一个新项目:File&gt;新&gt;新项目;
选择适合您的项目类型(适合使用命令行工具);
将SimpleCar.c / h和CarApp.c添加到您的项目中;删除旧的main.c;
(4.如果您选择其他命令行工具的项目类型,而不是将CarApp.c添加到项目中,则应将main()函数的内容复制到您的-awakeFromNib
函数中。 ApplicationDelegate。)
答案 1 :(得分:1)
看起来你刚刚创建了一个没有Xcode项目的Xcode工作区。这是一个你可以使用的项目:
http://www.markdouma.com/developer/CarApp.zip
通常,您只需选择文件&gt;用于创建新项目的新项目。您可能希望为此特定项目使用基于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