Objective C 2.0 是否发生了如此大的变化以至于旧代码将不再运行? Apple 目前只有 Obj C 吗?
我有 Stephen Kochan 于 2003 年出版的 Programming in Objective C 和 Programming in Objective-C 2.0 (2nd Edition) 出版于 2009 年。两本都是优秀的书籍,我正在刷新我的 Obj C 技能。
在这两个版本中,都有“分数与类”程序的列表。第一版列出3.4,第二版列出3.2。
下面是第一版中的清单 3.4:
#import <stdio.h>
#import <objc/Object.h>
///Interface section
@interface Fraction: Object
{
int numerator;
int denominator;
}
-(void) print;
-(void) setNumerator: (int) n;
-(void) setDenominator: (int) d;
-(id)init;
@end
//Implementation section
@implementation Fraction;
-(void) print
{
printf(" %i/%i", numerator, denominator);
}
-(void) setNumerator:(int)n
{
numerator=n;
}
-(void) setDenominator:(int)d
{
denominator=d;
}
-(int) numerator {
return numerator;
}
-(int) denominator {
return denominator;
}
@end //Implementation
// Program section
int main (int argc, const char * argv[])
{
Fraction *myFraction;
myFraction=[Fraction alloc];
myFraction=[Fraction init];
[myFraction setNumerator:1];
[myFraction setDenominator:3];
printf("The value is:");
[myFraction print];
printf("\n");
[myFraction free];
return 0;
}
第二版变得更加以 Apple/OS X 为中心。正文不再关注GCC,而是更关注xcode。该列表被转换为使用 OS X Foundation 类框架,而不是通用的 objc/Object.h 导入。
这里列出了第二版中的 3.4:
// program to work with fractions - class version
#import <Foundation/Foundation.h>
//---- @interface section ----
@interface Fraction: NSObject
{
int numerator;
int denominator;
}
-(void) print;
-(void) setNumerator: (int) n;
-(void) setDenominator: (int) d;
@end
//----@implementation section ----
@implementation Fraction
-(void) print
{
NSLog (@"%i/%i", numerator, denominator);
}
-(void) setNumerator: (int) n
{
numerator = n;
}
-(void) setDenominator: (int) d
{
denominator = d;
}
@end
//---- program section ----
int main (int argc, char *argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
Fraction *myFraction;
// Create an instance of a fraction
myFraction = [Fraction alloc];
myFraction = [myFraction init];
// Set fraction to 1/3
[myFraction setNumerator: 1];
[myFraction setDenominator: 3];
// Display the fraction using print method
NSLog (@"The value of myFraction is:");
[myFraction print];
[myFraction release];
[pool drain];
return 0;
}
当然,旧版本不能在较新的 XCODE 上编译,我并不觉得这非常令人惊讶。但是,如果在 Linux 或 Windows 上的最新版本的 GCC 上编译,旧版本代码将不再运行。
具体的运行时错误是找不到init方法
,但Kochan书中指出,init方法不需要在从Object
派生的类上定义。事实上,您不需要在 NSObject
上定义 -init
-alloc
或 free
但 gcc 4.2.1 警告说它们没有为 Object 定义。
我假设当 Kochan 出版他的第一本书时,这段代码可以成功编译和执行。我相信 Foundation 类和 NSObject 是 Apple 独有的。
我可以编译并运行 30 年前的 C 代码,但 7 年前的 Objective C 不再可用? Objective C 本质上是否已经成为 Apple 独有的语言,除了 Apple 独有的编译器和技术之外没有真正的支持?这就是问题所在。
I have both Stephen Kochan's Programming in Objective C published in 2003 and Programming in Objective-C 2.0 (2nd Edition) published in 2009. Both are excellent books, and I am refreshing my Obj C skills.
In both editions, there is a listing for the Fraction with Classes program. It is listing 3.4 in the first edition, listing 3.2 in the second edition.
Here is listing 3.4 from the first edition:
#import <stdio.h>
#import <objc/Object.h>
///Interface section
@interface Fraction: Object
{
int numerator;
int denominator;
}
-(void) print;
-(void) setNumerator: (int) n;
-(void) setDenominator: (int) d;
-(id)init;
@end
//Implementation section
@implementation Fraction;
-(void) print
{
printf(" %i/%i", numerator, denominator);
}
-(void) setNumerator:(int)n
{
numerator=n;
}
-(void) setDenominator:(int)d
{
denominator=d;
}
-(int) numerator {
return numerator;
}
-(int) denominator {
return denominator;
}
@end //Implementation
// Program section
int main (int argc, const char * argv[])
{
Fraction *myFraction;
myFraction=[Fraction alloc];
myFraction=[Fraction init];
[myFraction setNumerator:1];
[myFraction setDenominator:3];
printf("The value is:");
[myFraction print];
printf("\n");
[myFraction free];
return 0;
}
The second edition became much more Apple/OS X centric. Instead of focusing on GCC, the text is more focused on xcode. Instead of the generic objc/Object.h
import, the listing were translated to use the OS X Foundation class framework.
Here is listing 3.4 from the second edition:
// program to work with fractions - class version
#import <Foundation/Foundation.h>
//---- @interface section ----
@interface Fraction: NSObject
{
int numerator;
int denominator;
}
-(void) print;
-(void) setNumerator: (int) n;
-(void) setDenominator: (int) d;
@end
//----@implementation section ----
@implementation Fraction
-(void) print
{
NSLog (@"%i/%i", numerator, denominator);
}
-(void) setNumerator: (int) n
{
numerator = n;
}
-(void) setDenominator: (int) d
{
denominator = d;
}
@end
//---- program section ----
int main (int argc, char *argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
Fraction *myFraction;
// Create an instance of a fraction
myFraction = [Fraction alloc];
myFraction = [myFraction init];
// Set fraction to 1/3
[myFraction setNumerator: 1];
[myFraction setDenominator: 3];
// Display the fraction using print method
NSLog (@"The value of myFraction is:");
[myFraction print];
[myFraction release];
[pool drain];
return 0;
}
Of course the older version does not compile on the newer XCODE, and I do not find that terribly surprising. However, the older edition code no longer runs if compiled on recent versions of GCC on Linux or Windows.
The specific run-time error is init method not found
but the Kochan book states that the init method need not be defined on a class derived from Object
. Indeed you do not need to define -init
-alloc
or free
on NSObject
but gcc 4.2.1 warns that they are not defined for Object.
I am assuming that this code could be successfully compiled and executed when Kochan put out his first book. The Foundation classes and NSObject, I believe, are Apple only.
I can compile and run 30 year-old C code, but 7 year old Objective C is not longer useable? Has Objective C, essentially, become an Apple only language with no real support outside of Apple only compilers and technologies? That is the question.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
Object位于一个库中,NSObject位于Apple和GNUStep的库中。这不是语言改变为不再向后兼容的问题,而是使用不同的库的问题。
语言发生了变化,但只是增加,而不是删除。不过,图书馆已经发生了变化。
Object is in one library, NSObject is in Apple's and GNUStep's library. It isn't a matter of the language changing to be no longer backward compatible, it is a matter of using a different library.
The language has changed, but only by adding, not removing. The libraries have changed, though.
这是不正确的。
“NSObject”是大约 1994 年 OPENSTEP API 以及后来的 Cocoa 的基类。如果您需要支持 OPENSTEP NeXT 之前的系统,您只会使用“Object”,因此令人惊讶的是它会在 2003 年出版的一本书中使用。
对于 OPENSTEP/GnuSTEP/Cocoa 开发,您使用“NSObject”。
That's not correct.
"NSObject" is the base class for the OPENSTEP API circa 1994, and later Cocoa. You would have only used "Object" if you needed to support pre-OPENSTEP NeXT systems, so it's surprising that it would be used in a book published in 2003.
For OPENSTEP/GnuSTEP/Cocoa development you use "NSObject".
较旧的代码实际上使用 MacOSX 的 gcc 进行编译,并带有警告:
并在运行时给出运行时错误。但这与苹果的运行时有关。
您在 Linux 或 Windows 上链接到什么?
[额外]
正如评论中所指出的,在版本 1 中,声明并调用了 -init,但没有声明和调用 -init
实施的。如果您注释掉声明它的行和行
在调用它的地方,它将编译并运行(在带有 gcc 的 macOS 上):
The older code does in fact compile with MacOSX's gcc, with a warning:
and gives a runtime error when run. But this is linking to Apple's runtime.
What are you linking to on linux or windows ?
[added]
As noted in the comments, in version 1, -init is declared and called, but not
implemented. If you comment out the line where it's declared and the line
where it's called, it will compile and run (on macosx with gcc):