属性

能在一定程度上简化代码,并且增强实例变量的访问安全性

属性的声明:使用@property声明属性  eg:@property NSSstring *name;相当于@interface中声明了两个方法

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

- (NSString *)name;

属性的实现:使用@synthesize实现属性 ,eg:@synthesize name = _name;

相当于@implementation 实现了

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

- (NSString *)name;

//Person.h
@interface Person : NSObject
{NSString *_name;   //姓名NSInteger _age;    //年龄
    CGFloat _score;NSString *_sex;
}
@property CGFloat score;
//可以把相同类型的属性放在同一行进行声明,但是通常分开写
@property NSString *name,*sex;
//等价于下面两行
//- (void)setName:(NSString *)name;//设置名字
//- (NSString *)name;//获得名字

@property NSInteger age;
//等价于下面两行
//- (void)setAge:(NSInteger)age;//设置年龄
//- (NSInteger)age;//获得年龄
@end
//Person.m
#import "Person.h"@implementation Person
//=号前面是你声明的属性
//=号后面填写setter为哪个实例变量赋值,getter获取哪个实例变量的值
@synthesize name = _name,sex = _sex,age = _age,score =_score;//可以写成一行,一般写成两行,一行可读性差
//@synthesize age = _age;//实现age属性
//@synthesize score = _score;//实现score属性
//- (void)setName:(NSString *)name//设置名字
//{
//    _name = name;
//}
//- (NSString *)name//获得名字
//{
//    return  _name;
//}
//- (void)setAge:(NSInteger)age//设置年龄
//{
//    _age = age;
//}
//- (NSInteger)age//获得年龄
//{
//    return _age;
//}
@end

属性的属性

第一类:读写性控制(readonly、readwrite、setter、getter)

如果读写性控制的关键字是readonly,是告诉编译器,只声明getter⽅方法(无setter⽅方法)。
例如:@property(readonly)NSString *name;

//等价于 - (NSString *)name;

如果是readwrite,告诉编译器,既声明setter⼜又声明getter。
例如: @property(readwrite)NSString *name;

//等价于 - (NSString *)name;

- (void)setName:(NSString *)name; readwrite是读写性控制的默认设置。

第⼆类:原子性控制(nonatomic、atomic)

如果原子性控制的关键字是atomic。setter、getter⽅法在多线程访 问下是绝对安全的,即setter、getter内部做了多线程访问处理。原⼦ 性控制的默认设置是atomic

如果原子性控制的关键字是nonatomic。setter、getter⽅法内部不会 做多线程访问处理,仅是普通的setter、getter方法

程序开发过程中,setter、getter处都在用,如果使用atomic,

需要不断的对setter、getter加锁解锁以保证线程访问安全,会很占 ⽤系统资源,降低系统性能。

通常设置为nonatomic,某些属性需要线程安全的时候,才定义为 atomic。

例如:@property (readwrite,nonatomic)NSString *name;
//等价于 – (NSString *)name;

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

第三类:语义设置(assign、retain、copy)

如果语义设置的关键字是assign。setter、getter内部实现是直接赋值。

例如:@property(nonatomic,assign)NSString *name;
- (void)setName:(NSString *)name{

_name = name;
}

- (NSString *)name{
    return _name;

}

//assign修饰下,setter是直接为实例变量赋值

//assign修饰下,getter是直接获取实例变量

在如果语义设置的关键字是retain。setter、getter的内部实现会做内存优化。

//retain关键字下,setter 是企业必考的笔试题

例如:@property(nonatomic,retain)NSString *name;

- (void)setName:(NSString *)name{
    if(_name != name){

[_name release];

_name = [name retain];
    }

}

}

- (NSString *)name{

return [[_name retain]autorelease];

}

如果语义设置的关键字是copy。setter、getter的内部实现也会做内存优化。

例如:@property(nonatomic,copy)NSString *name;

- (void)setName:(NSString *)name{
    if(_name != name){

[_name release];

_name = [name copy];
    }

}

}

- (NSString *)name{

return [[_name retain]autorelease];

}

如果属性是⾮对象类型(⽐比如int,float等)属性的语义设置使用assign。

如果属性是对象类型(⽐如NSStrng、NSArray等)属性的语义设置使用retain。

如果属性是对象类型并且想得到参数的copy,使⽤用copy关键字。

-(instancetype)initWithName:(NSString *)name sex:(NSString *)sex age:(NSInteger)age
{self = [super init];if (self) {//给实例变量赋值,使用setter ,不再单独赋值,因为setter内部做了内存优化
        [self setName:name];[self setAge:age];[self setSex:sex];}return self;
}
//初始化以后就这样写

点语法

凡是符合系统默认setter、getter书写格式的⽅法都可以使⽤用点语 法。

例如:[person1 setName:@”zhangsan”];可以等价写成 person1.name = @”zhangsan”;。

NSString *name = [person1 name];可以等价写成
NSString *name = person1.name;

属性是⼀对getter、setter⽅法,点语法是属性的另一种调用格式

kvc

KVC(Key-Value-Coding),键值编码,是⼀种间接访问实例变量的方法.

key:键,⽤于标识实例变量

vlaue:实例变量对应的值

修改值

setValue:forKey:

setValue:forKeyPath:

setValue:forUndefinedKey:

setValuesForKeysWithDictionary:

获取值

valueForKey:

valueForKeyPath:

valueFoeUndefineKey:

注意事项

当key不存在的时候,会执⾏setValue:forUndefinedKey:

系统默认实现是抛出一个异常

一个kvc例子,一个Person类,一个A类

//A.h中代码
#import <Foundation/Foundation.h>@interface A : NSObject
{NSString *_name;
}- (void)printName;
@end
//A.m中代码
#import "A.h"@implementation A
-(void)printName
{NSLog(@"%@ ",_name);
}
@end
//Person.h中代码
#import <Foundation/Foundation.h>
#import "A.h"
@interface Person : NSObject{NSString *_name;
//    NSString *_sex;
    NSInteger _age;A *_a;
}
- (void)sayHi;
- (id)init;
@end
//Person.m中代码
#import "Person.h"
@implementation Person
-(void)sayHi
{NSLog(@"hello,this is %@ %ld years old   ",_name,_age);[_a printName];
}
//重写方法   当key不存在的时候会调用这个方法,系统的默认实现是抛出一个异常,我们可以重写这个方法.解决key不存在产生崩溃的问题
- (void)setValue:(id)value forUndefinedKey:(NSString *)key
{}
//当key为非对象类型,且value设置为nil的时候.会调用这个方法,系统默认实现是抛出一个异常,我们可以重写这个方法,解决value为nil的问题
- (void)setNilValueForKey:(NSString *)key
{}
-(id)init
{self = [super init];if (self) {_a = [[A alloc] init];}return self;
}
@end
//main.m中代码
#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[])
{Person *p1 = [[Person alloc] init];[p1 setValue:@"张三" forKey:@"name"];//kvc赋值[p1 setValue:@18 forKey:@"age"];[p1 sayHi];[p1 setValuesForKeysWithDictionary:@{@"name": @"张三",@"age": @18,@"sex": @"男"}];//比较好用
    [p1 sayHi];[p1 setValue:@"哇哈哈" forKeyPath:@"a.name"];[p1 sayHi];return 0;
}

转载于:https://www.cnblogs.com/limicheng/p/3821706.html

iOS学习笔记---oc语言第八天相关推荐

  1. iOS学习笔记---oc语言第三天

    继承.初始化方法 一.继承 继承的上层:父类  继承的下层:子类 继承是单向的,不能相互继承 继承具有传递性:A继承于B,B继承于C,A具有B和C的特征和行为 子类能继承父类全部的特征和行为(私有变量 ...

  2. IOS学习笔记07---C语言函数-scanf函数

    2013/8/7 IOS学习笔记07---C语言函数-scanf函数 ------------------------------ qq交流群:创梦技术交流群:251572072            ...

  3. IOS学习笔记07---C语言函数-printf函数

    IOS学习笔记07---C语言函数-printf函数 0 7.C语言5-printf函数 ------------------------- ----------------------------- ...

  4. IOS学习笔记06---C语言函数

    IOS学习笔记06---C语言函数 --------------------------------------------  qq交流群:创梦技术交流群:251572072              ...

  5. IOS学习笔记05---C语言程序的开发运行过程

    IOS学习笔记05---C语言程序的开发运行过程 0 5.C语言3-C语言程序的开发运行过程 ----------------------------------------------------- ...

  6. IOS学习笔记03---C语言概述

    IOS学习笔记03---C语言概述 0 3.C语言1-C语言概述         qq交流群:创梦技术交流群:251572072                        创梦网络赚钱群:2483 ...

  7. 黑马程序员- IOS学习笔记-OC三大特性

    ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 封装 set方法 1.作用:提供一个方法给外界设置成员变量值,可以在方法里面对参数进行相应过滤 ...

  8. nltk和python的关系_NLTK学习笔记(一):语言处理和Python

    目录 nltk资料下载 import nltk nltk.download() 其中,download() 参数默认是all,可以在脚本里面加上nltk.download(需要的资料库) 来进行下载 ...

  9. IOS学习笔记04---编写第一个C语言程序-Hello World

    IOS学习笔记04---编写第一个C语言程序-Hello World --------------------------------------------------------         ...

最新文章

  1. EPSON机械臂TCP通讯,实现手眼标定(附EPSON代码)
  2. java object 转byte_Java将对象Object转换成Byte字节数组
  3. java获取单击内容,java – 单击菜单链接时,获取元素不是可点击的异常
  4. JavaScript的理解记录(6)
  5. Spring Boot 操作 Memcache
  6. mysql 数值型注入_slq-注入总结(中)
  7. Spring Controller – Spring MVC控制器
  8. Virtualbox以及VWare在Win10下的不兼容
  9. Spring Boot 菜鸟教程 1 HelloWorld
  10. BigWorld用到的第三方库
  11. Python实现B样条代码
  12. Redis 入门指南
  13. js左右弹性滚动对联广告代码
  14. XJOI 7623 maoge数
  15. python降低图片分辨率_Python批量更改图片分辨率
  16. linux免费邮件服务器,Linux 电子邮件服务器的搭建
  17. png图片的文件存储格式
  18. Unity制作AR图片和视频展示
  19. “搬砖”机器人两天盖一栋房?泥瓦匠表示很心累
  20. 【5G安全系列】NAS层安全密钥衍生——USIM相关密钥的衍生

热门文章

  1. 立体匹配算法实现之:AdaptWeight
  2. HashMap 你真的了解吗?
  3. Confluence 6 如何保持我空间的整洁
  4. RabbitMQ 安装和简单测试
  5. 如何让PhpStorm同时打开多个项目?(多项目并存的问题)
  6. zabbix专题:第三章 Zabbix Agent客户端安装详解
  7. 我们不要框计算 我们要更好的搜索体验
  8. 集成ACEGI 进行权限控制
  9. 【干货】不同场景下 如何进行MySQL迁移
  10. 201671010128 2017-11-05《Java程序设计》之集合