0

我正在尝试运行以下代码:

#import <stdio.h>
#import <Foundation/NSObject.h>

//--------@interface section--------

@interface Fraction: NSObject {
   int numerator;
   int denominator;
}

-(void) setNumerator: (int) n;
-(void) setDenominator: (int) d;
-(void) print;

@end

//-------@implementation section-------

@implementation Fraction;

//getters

-(int) numerator {
    return numerator;
}

-(int) denominator {
    return denominator;
}

//setters

-(void) setNumerator: (int) num {
    numerator = num;
}

-(void) setDenominator: (int) denom {   
    denominator = denom;
}

//other

-(void) print {
    printf("The value of the fraction is %i/%i\n", numerator, denominator);
}

@end


//---------program section---------

int main(void) {
    Fraction *myFract;

    myFract = [Fraction new];

    [myFract setNumerator: 1];
    [myFract setDenominator: 3];

    printf("The numerator is %i, and the denominator is %i\n", 
                [myFract numerator], [myFract denominator]);
    [myFract print];

    [myFract free];

    return 0;
}

当我编译它

$gcc -framework Foundation p10.m 

我得到了。错误:

Program19_2.m: In function ‘main’:
Program19_2.m:55:2: warning: ‘Fraction’ may not respond to ‘+new’ [enabled by default] 
Program19_2.m:55:2: warning: (Messages without a matching method signature [enabled by
default]
Program19_2.m:55:2: warning: will be assumed to return ‘id’ and accept [enabled by
default]
Program19_2.m:55:2: warning: ‘...’ as arguments.) [enabled by default]
Program19_2.m:64:2: warning: ‘Fraction’ may not respond to ‘-free’ [enabled by default]
/tmp/ccVRbEBu.o: In function `main':
Program19_2.m:(.text+0x6d): undefined reference to `objc_get_class'
Program19_2.m:(.text+0x7f): undefined reference to `objc_msg_lookup'
Program19_2.m:(.text+0xa4): undefined reference to `objc_msg_lookup'
Program19_2.m:(.text+0xcd): undefined reference to `objc_msg_lookup'
Program19_2.m:(.text+0xf6): undefined reference to `objc_msg_lookup'
Program19_2.m:(.text+0x119): undefined reference to `objc_msg_lookup'
/tmp/ccVRbEBu.o:Program19_2.m:(.text+0x14e): more undefined references to
`objc_msg_lookup' follow
/tmp/ccVRbEBu.o: In function `__objc_gnu_init':
Program19_2.m:(.text+0x19a): undefined reference to `__objc_exec_class'
/tmp/ccVRbEBu.o:(.data+0x148): undefined reference to `__objc_class_name_Object'
collect2: error: ld returned 1 exit status

我只是从教科书中复制代码。更改我导入的库,因为它们现在已弃用 (Object.h)。我想知道为什么它不运行。我编译程序的方式有问题吗?

4

5 回答 5

2

您遇到的问题是您的书早于现代Objective-C(即Objective-C 2.0)。

这个Object类已经存在了几十年,但自从引入了 NeXTSTEP 框架后,在某种程度上它已经过时了。在没有 NeXTSTEP 框架的情况下编写 Objective-C 是非常罕见的(无论是 Apple 的 Foundation 还是 GNU 的 GNUstep)。

忘记学习Object。尽管您的书可能会教您一些 Objective-C 的基础知识,但它不会教您该语言中真正改变您编程方式的任何最新进展(包括块、属性等)。

于 2013-07-26T12:11:52.860 回答
1

如果 gcc 找不到 Object.h,它会给出一个错误指示。问题是 Apple 从Object.hObjective-C 2.0 中删除了大部分方法(或者至少是它的接口)。

The main reason your program is giving these errors is that gcc is not including the Object class.

相反,您应该继承 NSObject 并包含 Foundation 框架。

于 2013-07-26T09:50:20.857 回答
0

一个好的开始是安装clang..应该至少是3.2(我使用trunk,因为它似乎对ObjC++的问题较少),让它使用GNUstep aka GNUstep运行时附带的libobjc,而不是GCC。如果您不需要 GCC 来做其他任何事情,请卸载 GCC 和它附带的任何 libobjc,只需使用 clang。使用 GNUstep+GNUmakefile 构建项目是个好主意,有教程你可以谷歌搜索。

于 2013-07-27T08:53:00.537 回答
0
Program19_2.m:55:2: warning: ‘Fraction’ may not respond to ‘+new’ [enabled by default]

我不明白那个错误。我只是看了看,/usr/include/objc/Object.h界面肯定有new。唯一奇怪的是,如果您使用的Object#defineObjective-C 2.0,它就会被淘汰,但是您应该得到一个接口根本不存在的错误。也许其他一些头文件有一个前向声明Object。尝试用-Eflag 编译,看看预处理的结果是什么。

am19_2.m:64:2: warning: ‘Fraction’ may not respond to ‘-free’ [enabled by default]

这是由与第一个错误相同的问题引起的。

Program19_2.m:(.text+0x6d): undefined reference to `objc_get_class'

这种形式的所有错误都是由于您没有将程序与 Objective-C 运行时链接起来造成的。您可能可以通过以下方式摆脱它们:

gcc p10.m  -lobjc

以上都很好,但真正的问题是你的教科书已经过时多年了。我在 10 多年前第一次开始使用 Objective-C 并且已经没有人将Object其用作基类。您需要找到一本使用 Foundation 和 Cocoa 中的类的书 - 开始的那些NS

于 2013-07-26T12:00:11.827 回答
0

使用alloc然后 init初始化,释放内存使用release

另请注意声明为

-(void) setNumerator: (int) n;
-(void) setDenominator: (int) d;

实施为

//二传手

-(void) setNumerator: (int) num 
-(void) setDenominator: (int) denom

利用

-(void) setNumerator: (int) n {
    numerator = num;
}

-(void) setDenominator: (int) d {   
    denominator = denom;
}
于 2013-07-26T09:50:59.150 回答