Objective-C中的属性和实例变量
我对Objective-C中的属性和实例变量感到相当困惑 Aaron Hillegass的“MacOSX的可可编程”我已经讲了一半了,一切都合乎逻辑。您可以这样声明一个类:Objective-C中的属性和实例变量,objective-c,cocoa,cocoa-touch,properties,instance-variables,Objective C,Cocoa,Cocoa Touch,Properties,Instance Variables,我对Objective-C中的属性和实例变量感到相当困惑 Aaron Hillegass的“MacOSX的可可编程”我已经讲了一半了,一切都合乎逻辑。您可以这样声明一个类: @class Something; @interface MyClass : NSObject { NSString *name; NSArray *items; Something *something; IBOutlet NSTextField *myTextField; } @p
@class Something;
@interface MyClass : NSObject {
NSString *name;
NSArray *items;
Something *something;
IBOutlet NSTextField *myTextField;
}
@property (nonatomic, retain) NSString *name;
@property (nonatomic, retain) NSArray *items;
- 由于其他对象需要操作我们的
和名称
实例变量,因此我们使用项
/@property
为它们生成访问器/变异器。在我们的类中,我们不使用访问器/变异器,而是直接与实例变量交互@synthesis
只是我们将在类中使用的一个实例变量,因为没有其他人需要使用它,所以我们不为它创建一对访问器和变异器something
- 我们需要与UI中的文本字段交互,因此我们为它声明一个
,连接它,我们就完成了IBOutlet
IBOutlets
声明属性,并使用访问器/变异器与类中的实例变量进行交互(例如,他们将编写[self-setName:@“Test”]
而不是name=@“Test”
)
为什么??发生了什么事?这些差异是iPhone特有的吗?声明所有实例变量的属性、声明IBOutlets的属性以及在自己的类中使用访问器/变异器有什么好处?在iPhone世界中,没有可用的垃圾收集器。您必须小心地使用引用计数管理内存。考虑到这一点,考虑一下:之间的区别。
name = @"Test";
及
如果直接设置实例变量而不事先考虑,则会丢失对上一个值的引用,并且无法调整其保留计数(您应该手动执行release
d)。如果您通过属性访问它,它将自动为您处理,同时增加新指定对象的保留计数
基本概念并非特定于iPhone,但在没有垃圾收集器的环境中,它变得至关重要。属性用于生成实例变量的访问器,没有神奇的事情发生。 您可以手动实现相同的访问器 您可以在Aaron Hillegass的书中找到成员变量的3种内存管理策略的示例。它们是
assign/copy/retain
。您可以根据需要为给定变量选择其中一个
我想你了解Objective-c中的内存管理
访问器隐藏了每个变量内存管理的复杂性和差异
例如:
name = @"Test"
是一个简单的赋值,name
现在引用了NSString@“Test”
。但是,您可以决定使用复制
或保留
。无论选择哪个版本的内存管理,访问器都会隐藏复杂性,并且始终使用(或类似)选项访问变量:
现在setName:
可以使用assign/copy或retain
,您不必担心它
我的猜测是,iPhone教程使用属性使新开发人员能够更轻松地完成内存管理(尽管使用属性生成适当的访问器比每次手动实现它们更方便)
然而,在iPhone的世界里,情况似乎有所不同。人们为每个实例变量声明属性,为IBOutlets
声明属性,并使用访问器/变异器与类内的实例变量交互(例如,他们将编写[self-setName:@“Test”]
,而不是name=@“Test”
)
这不是iPhone特有的。除了在init
方法和dealloc
方法中之外,始终使用访问器是一种良好的做法。主要的好处,尤其是在Mac上(使用Cocoa绑定),是使用访问器意味着免费的KVO通知
人们“为每个实例变量声明属性”的原因很可能是因为他们所有的实例变量都是他们想作为属性公开的东西。如果他们有一些他们想保持私有的东西,他们不会在头文件中声明它的属性。(但是,他们可以在实现文件的类扩展中为其创建属性,以便获得上述免费KVO通知。)
在我看来,为门店申报房产是过分的。我不认为这有什么意义。如果您不创建属性,nib加载程序将通过直接实例变量访问来设置出口,这对于该任务非常合适。我认为现代开发已经做出了非常强烈的尝试来识别、定义和应用最佳实践 在这些最佳实践中,我们发现了连续性和一致性
除了争论在
init
和dealoc
方法中使用访问器之外,访问器通常应该一直使用(在类内部和外部),因为它们提供的好处包括多态var实现(都允许抽象和重构)并促进这些连续性和一致性的最佳做法。当以这种方式做事情并充分利用语言的能力时,面向对象语言的基本好处就会发挥作用。正如任何一位高级程序员通常会证明的那样,在编码过程中始终保持一致是一个经常被忽视的好处。你可以这样写
//MyClass.h
@class Something;
@interface MyClass : NSObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSArray *items;
@end
//MyClass.m
@interface MyClass()
@property (nonatomic, strong) IBOutlet NSTextField *myTextField;
@property (nonatomic, strong) Something *something;
@end
…但是,在“MacOSX的Cocoa编程”中,Aaron Hillegass没有使用垃圾收集器。。。我们手动管理内存……史蒂夫:我还没看过指南。无论如何,如果您不使用属性,并且在任何地方指定实例变量,那么
[self setName:@"Test"]
[self name]
//MyClass.h
@class Something;
@interface MyClass : NSObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSArray *items;
@end
//MyClass.m
@interface MyClass()
@property (nonatomic, strong) IBOutlet NSTextField *myTextField;
@property (nonatomic, strong) Something *something;
@end