我不完全确定这里的情况,但让我们先看一些示例代码。
//// Book.h
@interface Book : NSObject
@property (nonatomic, retain) NSString *title;
@property (nonatomic, retain) NSString *author;
@property (nonatomic, assign) NSInteger numberOfPages;
- (id)initWithTitle:(NSString *)aTitle andAuthor:(NSString *)anAuthor;
@end
//// Book.m
@implementation Book
- (id)initWithTitle:(NSString *)aTitle andAuthor:(NSString *)anAuthor {
if ( self = [super init] ) {
self.title = aTitle;
self.author = anAuthor;
}
return self;
}
- (void)dealloc {
self.title = nil;
self.author = nil;
[super dealloc];
}
@end
因此,在此我们建立一个类并为其提供 3 个属性,title 和 author(它们都是 NSString 的)和 numberOfPages(它是一个整数)。在类中,我们可以通过调用诸如self.propertyName = value
.
这一切都很好,但实际上发生了什么?好吧,让我们再更新一下标题:
//// Book.h
@interface Book : NSObject {
@private
NSString *_title;
NSString *_author;
NSInteger _numberOfPages;
}
@property (nonatomic, retain) NSString *title;
@property (nonatomic, retain) NSString *author;
@property (nonatomic, assign) NSInteger numberOfPages;
- (id)initWithTitle:(NSString *)aTitle andAuthor:(NSString *)anAuthor;
@end
在此,我们刚刚明确定义了编译器通常会通过@property
构造推断的内容。这些新添加的内容就是我们所说的实例变量或 ivars,并且是您分配给属性的值的实际存储位置。
但是,如果您还不能 100% 适应内存管理,那么操作 ivars 可能会很危险。即使您使用的是 ARC,您仍然应该了解该管理是如何工作的。
所以我们现在已经公开了这些属性实际存储数据的位置,但是那个@private
工作呢?这到底是怎么回事?@private
是一系列关键字的一部分,这些关键字有助于表示某物的“可访问性范围”。该系列中的其他两个关键字是@protected
and @public
,但后两个关键字的使用很少,如果不是不常见的话。这些关键字负责说明允许您访问事物的位置。这是它们的快速定义。
@public可以从任何地方自由访问,甚至在对象本身之外。然而,在 Cocoa 开发世界中,直接从其自己的类外部访问实例变量通常被认为是非常糟糕的做法,因此您几乎找不到如何去做。
@protected在类和它自己的子类中可以自由访问。不能在类/对象之外访问。
@private在课堂内可自由访问,但不能在其他任何地方访问。无法在类/对象之外甚至在其子类中访问。
因此,既然我们已经介绍了实际驱动属性背后的存储的原因,让我们看看在Book
应用程序的另一部分中使用我们的对象,例如AppDelegate
.
//// AppDelegate.m
@implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
Book *myBook = [[Book alloc] initWithTitle:@"pending title" andAuthor:@"Foo Bar"];
myBook.title = @"My Cool Book";
NSLog(@"%@ by %@", myBook.title, myBook.author);
[myBook release];
}
@end
在此我们创建了一个新的 Book 对象,用更专业的术语来说,我们定义了一个名为myBook
of的变量Book
并实例化它。在这里,我们使用-initWithTitle:andAuthor:
我们之前创建的方法来告诉 Book 对象它应该有一个初始标题和作者。
沿着这条线,我们会得到一些更奇怪的东西。myBook.title = @"My Cool Book";
您可能还记得我们在 Book.m 中有类似的东西,self.title = aTitle
. 那么这里发生了什么?为什么我们现在使用 myBook 而不是 self ,就像我们以前那样?原因是因为自我实际上是什么。
self
是 Objective-C 运行时提供的关键字,指的是您所在的当前对象。因此,如果我们在 Book.m 中编写代码,self 将引用当前的 Book 对象。如果我们在 AppDelegate.m 中使用 self,它将引用 AppDelegate。所以在我们之前的代码中,self 指的是当前的 Book 对象,就像我们的 myBook 对象现在指的是特定的 Book 对象一样。它们本质上是相等的(不完全是,但那是另一个讨论领域)。
这意味着可以通过 myBook 变量访问 Book 中的任何属性或方法,就像您在 Book.m 中使用 self 一样。所以我们也可以做
myBook.title = @"My Book";
myBook.author = @"Baz Quux";
myBook.numberOfPages = 100;
希望这会有所帮助(并回答了您的问题,如果没有,那么它可以作为希望了解更多有关属性和实例变量的人们的参考)