Objective-C 实例变量与属性的区别
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Objective-C 实例变量与属性的区别相关的知识,希望对你有一定的参考价值。
记得刚学习OC时,对实例变量和属性总是不太清楚。
比如下面代码中在打印Person类对象的名字时,什么时候用带“_”的name,NSLog(@"%@",p1->_name);
什么时候用不带“_”的name,NSLog(@"%@",p1.name);
现在回想起来也是挺有意思的过往,写下自己曾经的迷惘,纪念一下青春?。。。。
首先,使用实例变量编写代码。以及实例变量赋值要用到getter、setter方法。
@interface Person : NSObject
{
@public
NSString *_name; //定义实例变量_name
}
-(instancetype)initWithName:(NSString *)name; //初始化
-(void)setName:(NSString *)name; //setter方法
-(NSString *)name; //getter方法
@end
@implementation Person //实现部分
-(instancetype)initWithName:(NSString *)name{
if (self = [super init]) {
_name = name;
}
return self;
}
-(void)setName:(NSString *)name{
_name = name;
}
-(NSString *)name{
return _name;
}
@end
int main(int argc, const char * argv[]) { //主函数
Person *p1 = [[Person alloc] initWithName:@"zhangsan"];
NSLog(@"%@",p1->_name);
return 0;
}
以上代码,均使用的是实例变量。这个大家应该都明白。那么什么时候不用下划线呢?
使用属性编写代码(请比较两者的代码量)
首先明确两点:
1、属性的作用是生成setter以及getter方法的实现。并且如果.h文件中未定义对应的实例变量时,系统会生成一个“_属性名”的实例变量,但是生成的实例变量的可见度是私有的private。
2、OC中提供属性的目的:为了简化程序员的编码。
@interface Person : NSObject
@property(nonatomic,copy)NSString *name;
-(instancetype)initWithName:(NSString *)name;
@end
@implementation Person
-(instancetype)initWithName:(NSString *)name{
if (self = [super init]) {
_name = name;
}
return self;
}
@end
int main(int argc, const char * argv[]) {
Person *p1 = [[Person alloc] initWithName:@"zhangsan"];
NSLog(@"%@",p1.name); //属性是一对getter、getter方法,点语法是属性的另一种调用格式。
return 0;
}
此时打印,虽然属性也生成了对应的实例变量,但是实例变量是私有的,所有并不能直接打印实例变量。用点语法,相当于调用了getter方法,返回值依旧是实例变量存储的值。
因为定义属性时语义设置的关键字是copy。
setter内部实现
- (void)setGender:(NSString *)gender {
if (_gender != gender) {
[_gender release];
_gender = [gender copy];
}
}
getter内部实现
- (NSString *)gender {
return [[_gender retain] autorelease];
}
说到这里,应该能够理解属性与实例变量的区别了。
以上是关于Objective-C 实例变量与属性的区别的主要内容,如果未能解决你的问题,请参考以下文章