请帮忙!我在 objective-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
最佳答案
看起来您刚刚创建了一个没有Xcode项目的Xcode工作区。这是您可以使用的项目:
http://www.markdouma.com/developer/CarApp.zip
通常,您只需选择"file">“新建项目”即可创建一个新项目。您可能需要该特定项目的基于基金会的命令行程序。
不幸的是,本教程并未提供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
关于objective-c - objective-c undefined symbol 编译错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6231368/