day8: 属性、点语法、KVC

属性是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 <Foundation/Foundation.h>

@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 <Foundation/Foundation.h>

@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 <Foundation/Foundation.h>

@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 <Foundation/Foundation.h>

@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 <Foundation/Foundation.h>
#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 <Foundation/Foundation.h>
#import "Card2.h"

@interface Card : NSObject{
    //身份证号
    NSString * _number;
    Card2 * card2;
}

@end

Card.m

#import "Card.h"

@implementation Card

@end


Card2.h

#import <Foundation/Foundation.h>

@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 <Foundation/Foundation.h>
#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;        
    
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值