iOS学习笔记---oc语言第八天
属性
能在一定程度上简化代码,并且增强实例变量的访问安全性
属性的声明:使用@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:@ forKey:@"age"];
[p1 sayHi];
[p1 setValuesForKeysWithDictionary:@{@"name": @"张三",@"age": @,@"sex": @"男"}];//比较好用
[p1 sayHi];
[p1 setValue:@"哇哈哈" forKeyPath:@"a.name"];
[p1 sayHi];
return ;
}
iOS学习笔记---oc语言第八天的更多相关文章
- iOS学习笔记---oc语言第一天
第一讲 初始类和对象 c语言的超集,允许在oc中使用c语言源代码.编译器兼容c语言程序 具备完善的面向对象特性 包含一个运行时系统 类库丰富 面向对象编程 oop 面向对象语言:c++ java ...
- iOS学习笔记---oc语言第五天
字典,数组 ,集排序 一.字典类 存储以下数据 name:张三; sex:男;age:18 film:风暴; playcount:10000次;price:60元 字典类用于保存具有映射关系(key- ...
- iOS学习笔记---oc语言第四天
字符串 数组 一.使用苹果帮助文档 学会使⽤用苹果帮助⽂文档是开发者的⼀一项技能 Inherits from 继承⾃自 Conforms to 遵循什么协议 Framework 属于哪个框架 Avai ...
- iOS学习笔记---oc语言第三天
继承.初始化方法 一.继承 继承的上层:父类 继承的下层:子类 继承是单向的,不能相互继承 继承具有传递性:A继承于B,B继承于C,A具有B和C的特征和行为 子类能继承父类全部的特征和行为(私有变量 ...
- iOS学习笔记---c语言第八天
指针 首先将变量a的地址存放在另一个变量中,比如存放在变量b中,然后通过变量b来间接引用变量a,间接读写变量a的值.用来存放变量地址的变量,就称为"指针变量" int *p=nul ...
- iOS学习笔记---oc语言第九天
初级内存管理 iOS应用程序出现crash(闪退),90%以上是内存问题////其他:数组越界,方法只声明没实现 内存问题体现在两个方面:内存溢出\野指针异常 内存溢出:程序运行超出内存上限 野指针异 ...
- iOS学习笔记---oc语言第六天
Block .数组高级 block本质上就是匿名函数(没有名称的函数) block语法和函数指针很相似 回顾函数 函数:C语⾔中,实现某一类功能的代码段. 完整的函数包含两部分:函数声明.函数定义 函 ...
- iOS学习笔记---oc语言第二天
实例变量与方法 一.实例变量的可见度 二.方法 oc中的方法分两种:类方法和实例方法 类方法:只能类使用 eg:+ (id)alloc 注:类方法中不能使用实例变量 实例方法:只能对象使用,eg:- ...
- iOS学习笔记---oc语言第十天
内存管理高级 一 属性的内部实现原理 assign retain copy assign 下的属性内部实现 setter方法 @property(nonatomic,assign)NSS ...
随机推荐
- 使用WebView加载HTML代码
使用EditText显示HTML字符串时,EditText不会对HTML标签进行任何解析,而是直接把所有HTML标签都显示出来-----就像用普通记事本显示一样:如果应用程序想重新对HTML字符串进行 ...
- javascript 错误处理
try{ var date=new Date(); date.test();//调用date的未定义的test方法; document.wrire("try块执行结束<br>&q ...
- 谷歌 不支持 activeX插件
因为Chrome浏览器42以上版本已经陆续不再支持NPAPI插件,也就是说,目前的迅雷插件.FLASH插件.支付宝插件.阿里旺旺插件.百度贴吧.网银等网站都受到一定程度的影响,本文分享给大家如何让谷歌 ...
- wp8.1 Study9:针对不同的屏幕和手机方向调整UI
一.预备知识 现在不同屏幕大小WP8.1手机越来越多,那么在设计UI时,这需要我们考虑这个问题.在WP中,比例因子(a scale factor)能很好的解决问题,而且在微软系统的PC/平板/手机都是 ...
- wince6.0 开机启动定制的程序
1.prject.bib MediaApp.exe $(_FLATRELEASEDIR)\MediaApp.exe NK H MediaApp.lnk $(_FLATRELEASEDIR)\Media ...
- 使用plsql连接别人的oracle(转)
文章来源:http://www.linuxidc.com/Linux/2013-04/82738.htm oracle服务有时候我们觉得太大,所以我们只需要在本机上装一个oracle客户端和plsql ...
- SharePoint 2013 Nintex Workflow 工作流帮助(五)
博客地址 http://blog.csdn.net/foxdave 工作流动作 4. Assign To-Do Task(User interaction分组) 直观理解,指派待办任务给一个或多个用户 ...
- 《day09---继承-抽象类-接口》
//面向对象_继承_概述---单继承_多继承. //描述学生. /* class Student { //属性. String name; int age; //行为: void study() { ...
- HDU 4417 - Super Mario ( 划分树+二分 / 树状数组+离线处理+离散化)
题意:给一个数组,每次询问输出在区间[L,R]之间小于H的数字的个数. 此题可以使用划分树在线解决. 划分树可以快速查询区间第K小个数字.逆向思考,判断小于H的最大的一个数字是区间第几小数,即是答案. ...
- 上位机控制led
使用库函数,调试的结果在标红程序上,int main(void){ u8 a; u8 t; u8 len; u16 ti ...