objective-c学习札记第二天
今天主要内容
为什么需要点语法、点语法好处是什么
@property @synthesize如何使用
@property @synthesize编译器如何展开
如何使用点语法
@property 其他属性
为什么要设计点语法
为了方便别的程序员转到OC开发上来
为了让程序设计简单化
隐藏了内存管理细节
隐藏了多线程、同步、加锁细节
点语法
属性可以在不使用括号的情况下使用点语法
无需调用[foo value]可以使用foo.value来访问
虽然foo.value看起来像是直接访问value变量,
但是属性始终调用方法,而这些方法又可以访问对象的数据
例子
Dog.h头文件申明
@interface Dog : NSObjec {
int age;
}
-(void) setAge:(int)newAge;
-(int) age;
@end
Dog.m实现
#import "Dog.h"
@implementation Dog
-(void) setAge:(int)newAge {
age = newAge;
}
-(int)age{
return age;
}
@end
setter和getter函数
-(void) setAge:(int)newAge;
-(int) age;
类似于setAge:设置新值一般叫做setter函数
类似于age取值一般叫做getter函数
使用经典调用和点语法
Dog *dog = [[Dog alloc] init];
[dog setAge:100]; //经典方式
int dogAge = [dog age];
NSLog(@"Dog Age is %d", dogAge);
dog.age = 200; //点语法
dogAge = dog.age;
NSLog(@"Dog new Age is %d", dogAge);
点语法是编译器级别
dog.age = 200;
dogAge = [dog age];
编译器会把dog.age = 200;展开成 [dog setAge:200];
编译器会把dogAge = dog.age; 展开成dogAge = [dog age];函数调用
点语法setter和getter规范
setter函数展开规范
dog.age = 200;
[dog setAge:200];
getter函数展开规范
int dogAge = dog.age;
Int dogAge = [dog age];
@property
@property是让编译器自动产生函数申明
不用写正面2行代码
- (void)setAge:(int)newAge; //这一行可以删除
- (int) age; //这一行可以删除
@property int age; 这一行就可以代替上面的两行代码
@end
@synthesize //合成
@synthesize 就是编译器自动实现getter和setter函数
不用写下列代码
Dog.m使用@synthesize
@implementation Dog
@synthesize age; 这一行可以顶替下面6行,编译器也是展开成下面的这6行代码
-(void) setAge:(int)newAge {
age = newAge;
}
- (int) age {
return age;
}
@end
总结 这两种方式可以*组合
类内部age和self.age是不一样的
在Dog类内部可以直接访问age变量
直接访问age相当于age字段
self.age是调用getter或者setter函数
@property进一步说明
@interface Dog : NSObject {
int _age;
}
@property int age;
@end
@synthesize age = _age;
目的是避免函数名和字段重复
实例:
Dog类
@interface Dog : NSObject {
int _age;
}
@property int age;
@end
#import "Dog.h"
@implementation Dog
@synthesize age = _age;
@end
Dog.m @synthesize展开实现
#import "Dog.h"
@implementation Dog
-(void)setAge:(int)newAge {
_age = newAge;
}
-(int)age {
return _age;
}
@end
属性可以是:
readwrite(缺省), readonly 表示属性是可读写 ,也就是可以使用getter和setter,而readonly 只能使用getter
assign(缺省),retain,copy 表示属性如何存储,相当于=赋值
nonatomic 表示不用考虑线程安全问题
getter=..., steter=... 重新设置getter函数和settre函数名
实例:
readonly属性
文件Foo.h
@interface Foo : NSObject {
NSString *str;
}
@end
//表示str是只读的属性
@property(readonly) NSString *str;
文件Foo.m
#impoprt "Foo.h"
@synthesize str;
@implementation Foo
...
@end