2012-08-12 80 views
0

我有MyUnitClass宣布像这样实现:为什么这些“成员”变量的行为像静态?

@implementation MyUnitClass 
Unit* _unit = NULL; 

在for循环中,我迭代的次数和创建MyUnitClass的多个实例。 Unit表现得像一个静态变量。我有一个断点MyUnitClass init方法内设置,这是每一个类initalized时间我得到什么:

(gdb) print _unit 
$4 = (Unit *) 0x112340 
(gdb) print _unit 
$5 = (Unit *) 0x112340 

注:

我已经变量移动到已经解决了这个问题声明@interface。如果你回答了这个问题,那么看到一个可以找到这个信息的页面的链接就太棒了。

+2

Objective-C没有成员变量;它有实例变量。或多或少都是一样的,但命名的一致性有所帮助。 – bbum 2012-08-12 06:05:52

回答

3

正如Richard指出的那样,缺少大括号将var定义为全局变量。在声明实例变量方面,有几种方法:

Objective-C Programming Language中讨论了在@interface@implementation中声明实例变量。

所以,你可以在@interface,这是你在历史上将会看到的实例变量定义的最常见的地方定义一个实例变量x

@interface TestClass : NSObject 
{ 
    NSInteger x; 
} 
@end 

@implementation TestClass 

// define the methods 

@end 

正如上面的链接描述,但是,你也可以在@implementation定义它(虽然,因为习惯问题,我不认为你会看到这个非常频繁):

@interface TestClass : NSObject 

@end 

@implementation TestClass 
{ 
    NSInteger x; 
} 

// define the methods 

@end 

其实是有,你可以把你的实例变量一个第三名,在课程扩展中(稍后在same document中讨论)。在实践中,这意味着你可以有你的.h定义如下

// TestClass.h 

@interface TestClass : NSObject 

// define public properties and methods here 

@end 

和您的m如下:

// TestClass.m 

// this is the class extension 

@interface TestClass() 
{ 
    NSInteger x; 
} 
@end 

// this is the implementation 

@implementation TestClass 

// define the methods 

@end 

这最后一种方法(与@interface一.H,用类.M扩展名和@implementation)现在是Xcode模板在创建新类时使用的格式。实际上,这意味着您可以将公共声明放在.h文件中,并将您的私有@property和实例变量放入类扩展中。它只是让你的代码更清洁一些,使你不需要使用私有实现细节来混淆你的.h文件(这实际上就是你的类的公共接口)。例如变量,或许在@implementation中定义实例变量的先前技术是等价的,但我认为它不适用于@property声明,在这种情况下,类扩展会变得有用。

+0

实际上如果你有一个UIKit元素的子类,比如'UIViewController',Xcode只使用类扩展变体。但是,看到有多少人只是在他们的应用中划分子类,这是一个很容易犯的错误。 – 2012-08-12 13:22:04

+0

@ RichardJ.RossIII嗯,它只会自动为UIKit子类添加一个空白的类扩展?我没有注意到这一点。但是,显然,你可以使用任何你想要的类的类扩展。 – Rob 2012-08-12 14:11:50

8

这是因为你没有用花括号包围变量,使它成为一个全局变量。要修复,尝试将其定义是这样的:

@implementation MyObject { 
    unsigned int myVar; 
} 

// rest of implementation 

@end 

只能有一个@implementation块,所以如果是在.h文件中已经声明,那么成员将需要在此进行添加或整个块将需要移动到.m文件。

这是C语言的一个补遗,编译器并不完全知道你希望它是一个iVar,而不是全局的。

+0

我也见过这种表示法(在实现大括号的外侧):@synthesize preferences = __ preferences。我猜在这种情况下,它是一个普通的老成员,而不是全球性的。 – Brian 2012-08-12 01:02:56

+0

@rhooligan'@ synthesize'稍有不同,属性实现指令。引用[Objective-C编程语言](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProperties.html#//apple_ref/doc/uid/TP30001163- CH17-SW9):“你可以使用'@ synthesize'指令告诉编译器,如果你没有在@ @ implementation'块中提供它们,它应该为一个属性合成setter和/或getter方法。'@synthesize '指令还会合成一个适当的实例变量,如果它没有被另外声明。“ – Rob 2012-08-12 09:07:18

相关问题