博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
day8: 属性、点语法、KVC
阅读量:4220 次
发布时间:2019-05-26

本文共 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);}@end
Teacher.h

#import 
@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
Teacher.m

#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;}@end
Person2.h

#import 
@interface Person2 : NSObject{ NSString * _name; NSInteger _age;}-(void)setName:(NSString *)name;-(NSString *)name;-(void)setAge:(NSInteger)age;-(NSInteger)age;@end
Person2.m

#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;}@end
Student.h

#import 
@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
Student.m

#import "Student.h"@implementation Student@end
Student2.h

#import 
#import "Card.h"@interface Student2 : NSObject{ @private NSString * _name; NSInteger _age; Card * _card;}-(void)sayHi;@end
Student2.m

#import "Student2.h"@implementation Student2-(void)sayHi{    NSLog(@"我的名字是%@,我%ld岁了",_name,_age);}@end

Card.h

#import 
#import "Card2.h"@interface Card : NSObject{ //身份证号 NSString * _number; Card2 * card2;}@end
Card.m

#import "Card.h"@implementation Card@end
Card2.h

#import 
@interface Card2 : NSObject{ NSString * _cid; NSInteger _age;}-(void)setAge:(NSInteger)age;-(NSInteger)age;@end
Card2.m

#import "Card2.h"@implementation Card2-(void)setAge:(NSInteger)age{    _age =age;}-(NSInteger)age{        return _age;}@end
main.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/

你可能感兴趣的文章
bill老师培训(二)
查看>>
bill老师培训(一)
查看>>
编译原理-文法复习
查看>>
监考那时心情
查看>>
“批斗”大会
查看>>
信息资源管理
查看>>
信息资源管理
查看>>
BASIC-2 01字串 循环 显示32个二进制数
查看>>
ALGO-1 区间k大数查询 排序 查找
查看>>
ALGO-2 最大最小公倍数 贪心算法
查看>>
C#基础—面向对象
查看>>
操作系统各类的特点
查看>>
操作系统—死锁
查看>>
C#基础与技巧——类与里氏替换
查看>>
对思维导图的认识
查看>>
C# throw new Exception的使用
查看>>
C# 重构中遇到的问题
查看>>
ASP报表分页设置
查看>>
C# 机房重构-职责链模式 上机
查看>>
动态规划求解‘货币兑付问题’
查看>>