本文共 7720 字,大约阅读时间需要 25 分钟。
属性是OC2.0定义的语法,能在一定程度上简化程序代码,并且增强实例变量访问的安全性。
1、属性的声明:
@property(attribute) NSString * name; 声明了实例变量 NSString * name; 声明了setter getter方法 默认实现了setter getter实例方法 如果全部重写getter或setter时,则property为不声明实例变量,这种情况就需要在.m文件里用@synthesize name=_name; 1.1 atomic nonatomic atomic 默认属性 原子属性 保证多线程的安全性高 效率低 nonatomic 非原子性的 不能保证多线程的安全性 效率高 1.2 readonly readwrite readonly 只读 readwrite 默认属性 可读可写 1.3 assign retain copy assign 基本数据类型使用 如果属性是费对象类型,比如(int,float等)属性的语义设置为assign retain 用于OC对象 引用计数会加1 如果属性是对象类型,属性的语义设置为 retain copy 用于OC对象 引用计数会加1 如果属性是对象类型,并且想得到参数copy,使用copy关键字。 1.4 setter=settername getter=gettername 相当于对默认setter和getter方法的重命名,其他用法没有任何影响 引用计数: 主要是对内存有效的管理,而使用的一种规则 标记内存+1 new copy retain alloc 标记内存-1 release autorelease 属性 @Propert 属性的Attribute 第一类 读写控制(readonly readwrite setter getter) readonly:告诉编译器,只帮我声明和实现get方法就可以了,不可以写入数据 readwrite:可以读写数据 第二类 原子性控制(nonatomic atomic) atomic setter/getter在多线程访问下是绝对安全的,即setter、getter内部做了多线程访问处理,原子性控制的默认设置是atomic 优点:保证多线程访问的安全, 缺点:因为有加锁解锁的过程,运行效率是比较低。 nonatomic setter、getter方法内部不会做多线程访问处理,仅仅是普通的setter、getter方法。 优点:运行快、效率高、多线程不安全,常用的是非原子操作。 缺点: 第三类 语义设置(assign retain copy) OC当中对象类型一般用retain和copy 基本数据类型用assign点语法
凡是符合系统默认stter、getter书写格式的方法都可以使用点语法
本质上是setter和getter方法的调用 有等号的,等号左侧相当于setter方法; 没有等号的,相当于getter方法 当使用点语法赋值的时候 错误写法: 引起死循环:self.age = age; return self.age; KVC KVO KVC键值编码:key value coding 作用:间接访问实例变量 修改值: setValue:forkey: setValue:forkeyPath: setValue:forUndfinedKey: 当key不存在的时候,系统默认调用这个方法,并抛出异常 setValuesForKeysWithDictionary: 获取值 valueForKey: valueForKeyPath:valueForUndefinedKey:
Person.h
#import@interface Person : NSObject//{// //姓名// NSString * _name;// //年龄// NSInteger _age;// //性别// NSString * _sex;//}/* @property 相当于声明了实例变量、setter方法、getter方法 1、声明了实例变量,并且实例默认加下划线,如:_name; 2、声明了setter和getter方法 3、实现了setter和getter方法 当全部重写getter和setter方法的时候,@property就不会声明实例变量_name. */@property NSString * name;//-(void)setName:(NSString *)name;//-(NSString *)name;@property NSInteger age;//-(void)setAge:(NSInteger)age;//-(NSInteger)age;@property NSString * sex;//-(void)setSex:(NSString *)sex;//-(NSString *)sex;-(void)sayHi;@end
Person.m
#import "Person.h"@implementation Person//相当于@implementation 实现了setter、getter方法@synthesize name=_name;@synthesize age=_age,sex=_sex;//-(void)setName:(NSString *)name{// _name=name;//}//-(NSString *)name{// return _name;//}//-(void)setAge:(NSInteger)age{// _age=age;//}//-(NSInteger)age{// return _age;//}//-(void)setSex:(NSString *)sex{// _sex=sex;//}//-(NSString *)sex{// return _sex;//}-(void)sayHi{ NSLog(@"name = %@,age = %ld,sex = %@",_name,_age,_sex);}@endTeacher.h
#importTeacher.m@interface Teacher : NSObject@property(nonatomic,retain) NSString * aName;@property(nonatomic,retain) NSString * aNo;@property(nonatomic,retain) NSString * aClassName;-(instancetype)initWithName:(NSString *)aName andNo:(NSString *)aNo andClassName:(NSString *)aClassName;+(instancetype)initWithName:(NSString *)aName andNo:(NSString *)aNo andClassName:(NSString *)aClassName;@end
#import "Teacher.h"@implementation Teacher-(instancetype)initWithName:(NSString *)aName andNo:(NSString *)aNo andClassName:(NSString *)aClassName{ if (self = [super init]) { Teacher * t=[[Teacher alloc]initWithName:aName andNo:aNo andClassName:aClassName]; return t; } return self;}+(instancetype)initWithName:(NSString *)aName andNo:(NSString *)aNo andClassName:(NSString *)aClassName{ Teacher * t = [[Teacher alloc]initWithName:aName andNo:aNo andClassName:aClassName]; return t;}@endPerson2.h
#importPerson2.m@interface Person2 : NSObject{ NSString * _name; NSInteger _age;}-(void)setName:(NSString *)name;-(NSString *)name;-(void)setAge:(NSInteger)age;-(NSInteger)age;@end
#import "Person2.h"@implementation Person2-(void)setName:(NSString *)name{ if (_name!=name) { [_name release]; _name = [name retain]; }}-(NSString *)name{ return [[_name retain]autorelease];}-(void)setAge:(NSInteger)age{ _age=age;}-(NSInteger)age{ return _age;}@endStudent.h
#importStudent.m@interface Student : NSObject@property(nonatomic,assign) NSString * sname;@property(nonatomic,assign) NSString * sex;@property(nonatomic,assign) NSInteger age;-(instancetype)initWithName:(NSString *)name andSex:(NSString *)sex andAge:(NSInteger)age;//+(instancetype)initWithNam@end
#import "Student.h"@implementation Student@endStudent2.h
#importStudent2.m#import "Card.h"@interface Student2 : NSObject{ @private NSString * _name; NSInteger _age; Card * _card;}-(void)sayHi;@end
#import "Student2.h"@implementation Student2-(void)sayHi{ NSLog(@"我的名字是%@,我%ld岁了",_name,_age);}@end
Card.h
#importCard.m#import "Card2.h"@interface Card : NSObject{ //身份证号 NSString * _number; Card2 * card2;}@end
#import "Card.h"@implementation Card@endCard2.h
#importCard2.m@interface Card2 : NSObject{ NSString * _cid; NSInteger _age;}-(void)setAge:(NSInteger)age;-(NSInteger)age;@end
#import "Card2.h"@implementation Card2-(void)setAge:(NSInteger)age{ _age =age;}-(NSInteger)age{ return _age;}@endmain.m
#import#import "Person.h"#import "Teacher.h"#import "Student.h"#import "Person2.h"#import "Student2.h"#import "Card.h"#import "Card2.h"int main(int argc, const char * argv[]) { Person *p=[[Person alloc]init]; //stter方法 [p setName:@"zero"]; [p setAge:18]; [p setSex:@"m"]; //getter方法 NSLog(@"name is %@",[p name]); NSLog(@"age is %ld",[p age]); NSLog(@"sex is %@",[p sex]); // Teacher * t = [Teacher initWithName:@"hour" andNo:@"18" andClassName:@"BJ150742"];// [t setAName:@"军军"];// // [t setANo:@"18"];// [t setAClassName:@"5"];// // [t aName];// [t aNo];// [t aClassName]; Person2 * p2 = [[Person2 alloc]init]; [p2 setAge:18]; p2.age=18; p2.name=@"zhagnsan"; NSLog(@"%@,%ld",p2.name,p2.age); Card2 * ca2= [[Card2 alloc]init]; [ca2 setAge:25]; NSLog(@"ca2.age = %ld",ca2.age); //--------KVC------------- Student2 * stu = [[Student2 alloc]init]; [stu setValue:@"bobo" forKey:@"name"]; //setValue:forKey:不管实例变量的可见度都可以设置进去 //@18, 是一个数字对象类型,NSNumber类型 //@18 相当于[NSNumber numberWithInt:18] [stu setValue:@18 forKey:@"age"]; [stu setValue:[NSNumber numberWithInt:20] forKey:@"age"]; [stu sayHi]; NSString * name = [stu valueForKey:@"name"]; NSString * age = [stu valueForKey:@"age"]; NSInteger age2 = [age integerValue]; NSLog(@"name = %@,age2 = %ld",name,age2); //第二种 setValue:forKeyPath: Card * c = [[Card alloc]init]; [stu setValue:c forKey:@"card"]; NSLog(@"card = %@",[stu valueForKeyPath:@"card.number"]); //student访问card里的实例变量number [stu setValue:@"123456" forKeyPath:@"card.number"]; NSLog(@"%@",[stu valueForKeyPath:@"card.number"]); Card2 * c2 = [[Card2 alloc]init]; [c setValue:c2 forKey:@"card2"]; [stu setValue:@"c2id" forKeyPath:@"card.card2.cid"]; NSLog(@"%@",[stu valueForKeyPath:@"card.card2.cid"]); /* setValue:forKey: key是不能传入路径的 setValue:forKeyPath:keyPath 根据路径设置和取值 */ //第三种 setValuesForKeysWithDictionary [stu setValuesForKeysWithDictionary:@{@"name":@"huige",@"age":@"18"}];// NSString * nameStr = [stu valueForKey:@"name"];// NSString * ageStr = [stu valueForKey:@"age"]; [stu sayHi]; //第四种,当查找的key没有的时候,系统自动调用这个方法,setValue:forUndefinedKey: //这个方法是自动的,不是手工使用的 return 0; }
转载地址:http://soxmi.baihongyu.com/