我正在使用Stephen Kochan在他的“Objective-C,Programming 4编程”一书中使用基于Windows的GNUstep环境学习程序语言的例子。我正在使用gnustep mysys-system-0.29.0,gnustep-core-0.29.0和gnustep-devel-1.4.0安装。
现在参加Kochan书中第3章的节目。当我执行源代码时, 我得到两个unqiue对象打印出的相同实例变量值, 'frac1'和'frac2'。看来'frac1'对象的实例变量分子和分母的内存位置引用了'frac2'对象的相同内存位置。
当我在“frac2”中将分子设置为3并将分母设置为7时,'frac1'中的分子和分母被覆盖。为什么?我不知道为什么?。在为'frac1'和'frac2'打印唯一的实例变量时,我得到相同的分数3/7。
以下是我编译的源程序:
//========================
// ##copied from "Programming in Objective C" pages 30-44 - edition 4
#import <Foundation/Foundation.h>
// --- @interface section ----
@interface Fraction:NSObject
- (void)print;
-(void) setNumerator: (int) n;
-(void) setDenominator: (int) d;
@end
//----@implementation----
#include <stdio.h>
@implementation Fraction
//{
int numerator;
int denominator;
//}
- (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, const char * argv[])
{
//Fraction *myFraction;
// Create an instance of a Fraction
//myFraction = [Fraction alloc];
//myFraction = [myFraction init];
Fraction *frac1;
frac1 = [Fraction alloc];
frac1 = [frac1 init];
Fraction *frac2 = [[Fraction alloc] init];
// Set 1st fraction to 2/3
[frac1 setNumerator: 2];
[frac1 setDenominator: 3];
// Set 2nd fraction to 3/7
[frac2 setNumerator: 3];
[frac2 setDenominator: 7];
// Display the fractions
// 'frac1' print should display fraction 2/3, however 3/7 is displayed
NSLog (@"first print is:");
[frac1 print];
// 'frac2' print displays fraction 3/7, as expected.
NSLog (@"second print is:");
[frac2 print];
return 0;
}
//========================
答案 0 :(得分:3)
您已对{
和}
的声明周围的numerator
和denominator
进行了评论。我猜你是这样做的,因为当你离开大括号时你会遇到编译器错误。
我推断Kochan的书是为使用Apple目前的Objective-C编译器和运行时的程序员编写的,适用于iOS和64位Mac OS X.这也称为“新运行时”或“现代运行时”。此版本的编译器和运行时具有一个名为“非脆弱实例变量”的功能,它允许您将实例变量放在类实现中,而不是在类接口中。 Kochan的代码使用了这个非脆弱的实例变量功能。
您使用的GNU编译器和运行时不支持此功能。
有一个新的GNU Objective-C运行时支持此功能,但GNU编译器不支持它。你必须使用Apple的编译器(clang)和新的GNU运行时。我不知道在Windows上使用该设置是多么容易。
您可以在此处了解有关此问题的更多信息:http://wiki.gnustep.org/index.php/ObjC2_FAQ
解决方法是在界面中声明实例变量。 Tim Dean和Andrew Madsen的答案显示了语法。
答案 1 :(得分:2)
你的问题是你在类的@implementation而不是@interface中声明了分子和分母值。这使它们成为全局变量而不是您的类的实例变量。将您的界面更新为:
@interface Fraction:NSObject {
int numerator;
int denominator;
}
- (void)print;
-(void) setNumerator: (int) n;
-(void) setDenominator: (int) d;
@end
然后从@implementation部分删除声明。然后它应该像你期望的那样表现。
答案 2 :(得分:2)
问题是Fraction
的两个实例变量numerator
和denominator
实际上并未声明为实例变量,而是将它们声明为全局变量。您应该在@interface中声明它们,如下所示:
@interface Fraction:NSObject
{
int numerator;
int denominator;
}
-(void)print;
-(void) setNumerator: (int) n;
-(void) setDenominator: (int) d;
@end
全局变量可以由程序的任何部分查看和设置。当您在类的@interface部分中将变量声明为实例变量时,该类的每个实例都会获得自己的一组变量,而其他实例则无法直接查看/更改它们。