一、设置器与获取器
例子:头文件
#import <Foundation/Foundation.h>
@interface Person : NSObject
{
NSString* _name;
int _age;
}
-(void)setName:(NSString*)name;
-(NSString*)name;
-(void)setAge:(int)age;
-(int)age;
@end
源文件
#import "Person.h"
@implementation Person
-(void)setName:(NSString*)name{
_name = name;
}
-(NSString*)name{
return _name;
}
-(void)setAge:(int)age{
_age = age;
}
-(int)age{
return _age;
}
@end
main.m文件
#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
Person * p = [[Person alloc]init];
[p setAge:18];
[p setName:@"张无忌"];
NSLog(@"姓名:%@,年龄:%d",[p name],[p age]);
}
return 0;
}
运行结果
小结:
在OC中设置器和获取器的定义({}中的变量都是@protected外界无法直接访问的)
setter方法的定义:
1. set开头以去掉下划线的成员变量为setter方法名称:setAge
getter方法的定义:
1.getter方法名与变量同名
二、点语法
保持Person类的头文件和源文件
#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
Person * p = [[Person alloc]init];
//
// [p setAge:18];
// [p setName:@"张无忌"];
//
// NSLog(@"姓名:%@,年龄:%d",[p name],[p age]);
p.age = 18;
p.name = @"张无忌";
int a = p.age;
NSString * n = p.name;
NSLog(@"姓名:%@,年龄:%d",n,a);
}
return 0;
}
输出结果:
2015-05-29 20:12:04.646 设置器获取器[635:40938] 姓名:张无忌,年龄:18
语句:把原来的 [p setAge:18]换成 p.age = 18,这两种写法等价的。
当编译器遇到 p.age = 18时,会自动将代码展开为 [p setAge:18];
当编译器遇到 int a = p.age时,会自动将代码展开为 int a = [p age];
所以:OC中的点语法不是直接访问变量的,而是调用setter和getter方法的。
三、点语法与self的陷阱
self关键字:self就相当于C++中this指针,self谁调用它,它就指向谁。
-(void)setAge:(int)age
{
self.age = age;
}
self.age展开就是 [self setAge:age];就相当于无限循环的调用setAge函数。
四、@property @synthesize
1、@property 和@synthesize的使用:
先给例子:
头文件Person.h
#import <Foundation/Foundation.h>
@interface Person : NSObject
@property int a;
@end
源文件 .m
#import "Person.h"
@implementation Person
@end
.m文件
#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
Person * p = [[Person alloc]init];
p.a = 10;
NSLog(@"%d",p.a);
}
return 0;
}
插入断点输出结果:
总结:
1、用法:@property 类型名 变量名
2、如果在.h文件中用了@property int a;声明了一个属性,而在.m中没有用@synthesize a;那么编译器会自动生成带下划线的_a,如果在.m中用了@synthesize a;那么编译器生成变量是a,不带下划线。
将.m文件更改:
#import "Person.h"
@implementation Person
@synthesize a;
@end
结果:
2、@synthesize的另一个作用
先给例子:
.h文件Person.h
#import <Foundation/Foundation.h>
@interface Person : NSObject
@property int a;
@end
.m文件
#import "Person.h"
@implementation Person
@synthesize a = _b;//指定对应的实例变量
@end
#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
Person * p = [[Person alloc]init];
p.a = 10; //句点语法
NSLog(@"%d",p.a);
}
return 0;
}
生成的实例变量是_b而不是a
p.a = 10;
//调用的 p.a 内部操作
//[p setA:10];
//-(void)setA:(int)a
//{
// _b = a;
//}
另外:
@property生成的属性都是私有的变量,子类中也不能继承。生成的setter和getter方法是能够被继承和重写的。
可以在.m中重写setter和getter方法。但是setter和getter方法只能重写一个。