属性

 属性是Objective-C 2.0定义的语法,为实例变量提供了setter和getter方法的默认实现。能在一定程度上简化程序代码,并且增强实例变量的访问安全性。

 

 

 

// main.m

#import<Foundation/Foundation.h>

#import "Person.h"

#import "Teacher.h"

#import "Student.h"

#import "Phone.h"

 

int main(intargc, const char * argv[]) {

   @autoreleasepool {

//       //属性

//       Person *person = [[Person alloc] init];

//       

//       // 属性的使用语法

//       //    [消息的接受者方法名];

//       //      对象名.属性名 (点语法)

//       [person setGender:@"男"];

//       person.gender = @"女";

//       NSLog(@"%@ %@",person.gender,[person gender]);

//       

//       Teacher *teacher = [Teacher TeacherWithName:@"name"gender:@"gender" age:22];

//       [teachersayHi];

//       

//       Student *stu = [[Student alloc]init];

//       // 因为属性声明为readonly,因此不能赋值,但是可以取值。

//      //stu.name = @"tz";

//       NSLog(@"%@",stu.name);

//       stu.gender = @"女";

//       NSLog(@"%@",stu.gender);

//       

//       stu.age = 2222;

//       stu.gender = @"w";

//       stu.score = @"888";

 

 

        // KVC(key-value-coding)

       // 间接的为实例变量赋值取值

       //

 

       Phone *p = [[Phone alloc]init];

p.color = @"yellow";

NSLog(@"%@",p.color);

       // key值是@"实例变量名",实例变量可以带或者不带下划线,因为方法内部做了优化,没有下划线自动加下划线,。

       [psetValue:@"red" forKey:@"colors"];

NSLog(@"%@",[pvalueForKey:@"_color"]);

 

       // 将A类的对象a作为B类的实例变量,如果想通过kvc(键值路径)给a的实例变量赋值,那么需要先通过kvc给a对象赋值。

 

       Student *stu1 = [[Student alloc]init];

       // 通过kvc为 p 的实例变量stu赋值

       [p setValue:stu1 forKey:@"stu"];

       // 通过kvc为p的实例变量stu的name赋值

       [psetValue:@"zrt" forKeyPath:@"stu.name"];

       //通过路径赋值

NSString *s = [pvalueForKeyPath:@"stu.name"];

       // 打印

NSLog(@"%@ %@",s,p.stu.name);

 

       // 3 - (void)setValuesForKeysWithDictionary:(NSDictionary<NSString*,id> *)keyedValues

 

       // 通过字面量创建一个字典对象

NSDictionary *dic =@{@"color":@"brand",@"brand":@"兰博基尼",@"stu":stu1};

 

       // 通过kvc整体为类的实例变量赋值

       Phone *p1 = [[Phone alloc]init];

       [p1setValuesForKeysWithDictionary:dic];

NSLog(@"%@ %@%@",p1.color,p1.brand,p1.stu);

 

 

       // ARC 属性修饰词:assign,weak,strong,copy;

       //  assign 修饰费对象类型

       //  weak    修饰代理

       // strong   相当于  MRC中的retain

       //   copy 相当于  MRC 中的copy

 

 

 

    }

return 0;

}

 

 

 

 

 

//Person.h

 

#import<Foundation/Foundation.h>

 

@interface Person : NSObject

{

NSString *_name;

 

}

 

@property(nonatomic,retain) NSString*gender;

// 等同于下面两句话

//- (void)setGender:(NSString *)gender;

//- (NSString *)gender;

 

@property(nonatomic,assign) NSInteger age;

 

// 属性

// 1、属性的本质是setter,getter方法,它的作用是为实例变量赋值、取值。

// 2、属性名前面的数据类型决定了 setter方法的参数类型,getter 方法的返回值类型

// 3、属性名决定了方法名

 

// setter 和 getter 本质上是为实例变量赋值。

- (void)setName:(NSString *)name;

- (NSString *)name;

@end

 

 

// Person.m

 

#import "Person.h"

 

@implementation Person

 

// 若完全不写 @synthesize,默认生成_gender(带有下划线) 的实例变量名

//// 如果 @synthesize 属性名:不写 = 实例变量名,默认生成的实例变量名和属性名一样。

//@synthesize gender;

//- (instancetype)init{

//   gender = @"123";

//   return self;

//}

 

// 等号右边的实例变量称为当前类的私有实例变量,不能被子类以及外界访问。

//@synthesize gender = _address;

 

 

// //如果需要重写 setter 和 getter 方法,必须加上@synthesize属性名 = 实例变量名

//// xcode4.5 之后,系统默认实现了setter 和 getter 方法

@synthesize gender = _gender,age = _age;

 

- (void)setGender:(NSString *)gender{

   _gender = gender;

}

 

- (NSString *)gender{

return _gender;

}

 

 

 

- (void)setAge:(NSInteger)age{

   _age = age;

}

 

- (NSInteger)age{

return _age;

}

 

- (void)setName:(NSString *)name{

   _name = name;

}

 

- (NSString *)name{

return _name;

}

 

@end

 

 

 

 

 

 

//属性的属性

// 1 读写性控制readonly,readWrite

//如果属性声明为readonlyname只生成 getter 方法。

// 如果属性的读写性控制不写,默认为readwrite。

 

@property(readonly)NSString *name;

 

// 2、原子性控制,包含atomic(原子性控制),nonatomic(非原子性控制)。

//atomic 主要运用在线程安全这一块,一般我们用nonatomic,因为atomic会不断的加线程锁,降低处理效率

// 默认为atomic,一般我们用nonatomic。

 

@property(nonatomic)NSString *sex;

 

 

// 3、语义设置,包含assign,retain,copy

// 一般非对象类型我们用assign修饰

// 对象类型用retain,copy修饰,且需要复制的情况,我们才用到copy,一般我们使用retain

// 默认为assign

 

// 代理用 assign,防止循环引用

// block 用 copy,因为 block 在栈区,防止使用后释放,所以用 copy,拷贝一份到堆区,自己释放。

 

 

//Student.m

 

#import "Student.h"

 

@implementation Student

 

@synthesize gender = _gender,score =_score,age = _age;

 

 

 

// 重写属性的实现

// 语义设置为assign

- (void)setAge:(NSInteger)age{

   _age = age;

}

 

 

 

- (NSInteger)age{

return _age;

}

 

// 2、语义设置为retain

- (void)setGender:(NSString *)gender{

if (_gender != gender) {

       [_gender release];

       _gender = [gender retain];

    }

}

 

 

- (NSString *)gender{

return [[_gender retain]autorelease];

}

 

 

// 3、语义设置为copy

- (void)setScore:(NSString *)score{

if (_score != score) {

       [_score release];

       _score = [score copy];

    }

}

 

 

- (NSString *)score{

return [[_score retain]autorelease];

}

 

 

@synthesize school = _school;

- (void)setSchool:(NSString *)school{

if (_school != school) {

       [_school release];

       _school = [school retain] ;

    }

}

- (NSString *)school{

return [[_school retain] autorelease];

}

 

 

- (instancetype)initWithName:(NSString*)name gender:(NSString *)gender age:(NSInteger)age{

if (self = [super init]) {

       _name = name;

       _gender = gender;

       _age = age;

    }

return self;

}

 

 

 

+ (Student *)studentWithName:(NSString*)name gender:(NSString *)gender age:(NSInteger)age{

   Student *student = [[Student alloc]init];

return student;

}

 

- (void)sayHi{

NSLog(@"%@ %@%ld",_name,_gender,_age);

}

 

@end

 

 

 

 

 

 

 

 

 

 

// Phone.m

 

#import "Phone.h"

 

@implementation Phone

 

// 当设置实例变量的值的时候,无此key值,则执行这个方法。空实现就不会崩溃。

- (void)setValue:(id)valueforUndefinedKey:(NSString *)key{

if ([key hasPrefix:@"colors"]) {

       [selfsetValue:@"red" forKey:@"color"];

    }

}

 

// 当取值的时候,无此key值,会执行这个方法

- (id)valueForUndefinedKey:(NSString *)key{

NSLog(@"无此key");

return 0;

}

 

@end

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值