让代码书写更加简便

--1-- 设置器和访问器
1.1 setter
1.2 getter
--2-- 类的本质
2.1 类类型的对象
2.2 类的本质
2.3 如何获取类对象
2.4 类对象的使用
2.5 类对象的存储
--3-- SEL类型
3.1 SEL
--4-- @property关键字
4.1 基本概念
4.2 @property用法
4.3 @property使用注意事项
--5-- @synthesize关键字
5.1 @synthesize用法
5.2 @synthesize使用注意
5.3 @synthesize指定实例变量赋值
--6-- self关键字
6.1 介绍
6.2 在对象方法中使用self
6.3 用在类方法中使用self
-------------------------------------

【写在开头】

『在面向对象的编程中,封装是其一个重要的特性。封装将一个可供外部使用的接口暴露出来,隐藏了复杂的代码逻辑实现。

不可被外部任意存储是面向对象设计的本质,降低了数据被无用的可能性。

外部就可以通过设置器setter和访问器getter来对对象的属性进行设置和访问,而不是直接访问对象的属性(->)

在开发过程中,考虑到安全性要求,一般不再成员变量名前面使用@public、@protected等关键字修饰,而是使用Set方法来为对象提供成员变量的值,在set方法的内部也可以对一些不合理的赋值进行筛选过滤。』

--1-- 设置器和访问器

1.1 setter

setter方法(设置器):在set方法的内部可以对一些不合理的数据过滤筛选。set方法作用:为提供一个设置成员变量值的方法。

命名规范:

1)方法名必须以set开头

2)set后面跟上成员变量的名称,首字母大写

3)返回值一定是void

4)一定要接受一个参数,而且参数类型需要和成员变量的类型一致

5)形参名不能和变量名一样(成员变量名以_线开头,苹果官方推荐成员变量名前加_以示区分)

好处:

  1)不让数据暴露在外,保证了数据的安全性

  2)对设置的数据进行过滤

{
//成员属性
NSString *_name;
int _age;
}

setter

//setter
- (void)setName:(NSString *)name;
- (void)setAage:(int)age;

1.2 getter

作用:为调用者返回对象内部的成员变量

命名规范:

1)一定有返回值,返回值的类型和成员变量的类型一致

2)方法名和去掉下划线的成员变量名一样(此处与Java等语言不一样)

3)不需要接收任何参数

//getter
- (NSString *)name;
- (int)age;

--2-- 类的本质

2.1 类类型的对象

类的本质其实也是对象,只不过是class类型的对象,也叫做类对象

2.2 类对象

类对象

* 类对象在程序运行时一直存在

* 类对象是一种数据结构,存储类的基本信息:类大小,类名,类的版本以及消息与函数的映射表等

* 类对象所保存的信息是在程序编译时确定,在第一次使用该类的时候被加载到内存中

* 类对象代表类,class代表类对象,类方法属于类对象

* 如果消息的接收者是类名,则类名代表类对象

* 运行时,所有类的实例都由类对象生成,类对象会把实例的isa的值修改成自己的地址,每个实例的isa都指向该实例的类对象

* 从类对象里可以知道父类的信息、可以响应的方法等

* 类对象只能使用类方法,不能使用实例方法

2.3 如何获取类对象

1)通过实例对象获取

    Person *person = [[Person alloc] init]; //创建对象

    //通过实例对象获取类对象Dog
Class c1 = [person class]; //Class类型的是一个结构体指针
Class c2 = [person class]; NSLog(@"c1->%p", c1); //0x1000011d8
NSLog(@"c2->%p", c2); //0x1000011d8

2)通过类名获取(类名其实就是类对象)

    //通过类名获取类对象
Class c3 = [Person class]; NSLog(@"c3->%p", c3); //0x1000011d8

发现通过类名和实例获取对象,所获得的对象是同一个

实际上,都是获得了类对象Person class

2.4 类对象的使用

1)用类对象创建对象

两个测试方法:

//对象方法
- (void)test; //类方法
+ (void)test;

使用

    //用类对象来创建对象
Person *person2 = [[c1 alloc] init];
[person2 test]; //调用对象方法的test -test

2)用类对象来调用类方法

    //用类对象来调用类方法
[c1 test]; //调用类方法 +test

2.5 类对象的存储

isa指针

  • 每一个对象都包含一个isa指针.这个指针指向当前对象所属的类。
  • [p eat];表示给p所指向的对象发送一条eat消息,调用对象的eat方法,此时对象会顺着内部的isa指针找到存 储于类中的方法,执行。
  • isa是对象中的隐藏指针,指向创建这个对象的类。
  • 通过isa指针我们可以在运行的时候知道当前对象是属于那个Class(类)的。

--3-- SEL类型

3.1 SEL

SEL:全称selector,表示方法的存储位置

方法调用的原理:其实每个类加载到内存中对象的方法都会封装成一系列的SEL列表,SEL会保存着这个方法的信息(当然包括方法的内存地址),当要调用该方法的时候,对象会通过isa指针找到内存中对应的方法的内存地址然后再调用该方法,在找到该方法之后该类对象会把该SEL放入缓存中,以便第二次寻找的时候提高效率

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

[p test];

寻找方法的过程

1)首先把test这个方法名包装成SEL类型的数据

2)根据SEL数据找到对应的方法地址

3)根据方法地址调用相应的方法

4)注意:在这个操作过程中有缓存,第一次找的时候是一个一个的找,非常耗性能,之后再用到的时候就直接使用了

--4-- @property关键字

4.1 基本概念

@property是编译器的指令。(编译器指令是由编译器完成的)

好处是免去我们手工书写成员属性getter和setter方法繁琐的代码。

4.2 @property用法

格式:

  @property  类型名  方法名

如:

  @property  int  age;

相当于完成了age属性的set和get方法的声明和实现

- (void)setAge:(int)age;

- (void)age;

注意:

1、在Xcode4.4之前,用于帮我们实现get/set方法的声明

2、在Xcode4.4之后,有增强功能,连实现也自动完成了

Person.h->

/*
 省略了方法的声明
 相当于是替换了下面的这两句声明
 - (void)setAge:(int)age;
 - (int)age; 同时,还自动生成了对应的成员属性 _age,但是这个属性是私有的,外部只能通过setter/getter访问
 */
@property int age;

Person类中没有自定义 _age属性,但是@property自动生成了该属性:

@implementation Person
//对象方法
- (void)test{
NSLog(@"-TEST");
self->_age = ; //在这里可以看到,@property生成了一个_age属性
} //类方法
+ (void)test{
NSLog(@"+TEST");
}
@end

调用:

Person *person = [[Person alloc] init]; //创建对象

//此处 _age属性由@property生成
person.age = ; //设置成员属性
NSLog(@"person.age->%d", person.age); //

4.3 @property使用注意事项

在老式的代码中

@property只能写在@interface ...@end之间

@property用来自动生成成员变量get/set方法的声明(Xcode4.4之前)

告诉@property要生成的get/set方法声明的成员变量类型是声明

告诉@property要生成的get/set方法是哪个属性的,属性名去掉下划线

--5-- @synthesize关键字

5.1 @synthesize用法

@synthesize age;

写在.m文件中,表示对生成.h中变量age的get和set方法的实现

格式:

  @synthesize  方法名

注意:

如果使用@synthesize则变量名要先在.h文件中声明

.h

@property int age;

.m

@synthesize age;

展开形式如下:

@synthesize age;
//展开
- (void)setAge:(int)age{
self->age = age; //注意这里不是对Person原来的成员变量_age赋值,而是生成了一个变量age,然后对其进行赋值
//(如果这里写self,那么这个变量age也就相当于是个成员变量了) //所以使用@synthesize时,下面只打印了age和name的值,没有对_age和_name进行操作
//NSLog(@"age = %d, name = %@", age, name);
//NSLog(@"_age = %d, _name = %@", _age, _name);
}

5.2 @synthesize使用注意

Xcode4.4之前@property和@synthesize搭配使用,用于简化set和get方法的定义和实现

5.3 @synthesize指定实例变量赋值

声明

@property  int  a;

实现

@sythesize  a  =  _b;   //表示用a的get和set方法,修改属性b的值

相当于下面的代码:

   - (void) setA:(int)a{

  _b = a;

  }

   - (int)a{

  reurn _b;

  }

@interface Person : NSObject

@property NSString *name;
//如果两个实例变量的类型一致,如:age和weight,@property可以用逗号隔开变量,在一行上定义
@property int age, weight; //测试方法
- (void)test;
@end @implementation Person //用age的getter和setter方法,修改属性_age的值
@synthesize age = _age, name = _name, weight = _weight;
@end

--6-- self关键字

6.1 介绍

OC语言中的self,就相当于C++、Java中的this指针。

学会使用self,首先要搞清楚属性这一概念。

以及理解getter(访问器)和setter(设置器)方法,它到底有什么用?

设置器与访问器,提供外界操作 类内部属性的一个通道。

假如没有这个方法,外界怎么操作类的内部属性。

假如不提供这两个方法,那么这个属性的值,就不能为外界所改变。

因为类的属性,默认是@protect(受保护类型)。

self的应用场景

1)用在类方法中

2)用在对象方法中

3)访问成员变量

4)self在OC的内存管理特殊使用

6.2 在对象方法中使用self

//学生学习对象方法
- (void)study{ //此时self指代学生对象
NSLog(@"- self->%p", self); //0x1002001b0
}

6.3 用在类方法中使用self

//学生信息类方法
+ (void)info{ //此时self指代学生类
NSLog(@"+ self->%p", self); //0x1000013d0
}

查看:

    @autoreleasepool {

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

        //学生对象地址
NSLog(@"stu->%p", stu); //0x1002001b0 //学生类地址
NSLog(@"Student-%p", [Student class]); //0x1000013d0 //发送study和info消息
[Student info]; //0x1000013d0
[stu study]; //0x1002001b0
}

输出-->

综上总结:

self要指代谁?具体是要看self写在哪个方法中,

如果self写在对象方法中,则指代的就是当前方法的对象([类 new])

如果self写在类方法中,那么它指代的就是当前的类对象(类 class)

注意这里类对象和对象是两个概念

【写在结尾:】

『想起一首席慕容的诗:

一棵开花的树

如何让你遇见我
在我最美丽的时刻 为这
我已在佛前求了五百年
求佛让我们结一段尘缘
佛於是把我化做一棵树
长在你必经的路旁 阳光下
慎重地开满了花
朵朵都是我前世的盼望 当你走近
请你细听
那颤抖的叶
是我等待的热情 而当你终於无视地走过
在你身後落了一地的
朋友啊
那不是花瓣
那是我凋零的心』

OC-@property、self及类的本质的更多相关文章

  1. OC的特有语法-分类Category、 类的本质、description方法、SEL、NSLog输出增强、点语法、变量作用域、@property @synthesize关键字、Id、OC语言构造方法

    一. 分类-Category 1. 基本用途:Category  分类是OC特有的语言,依赖于类. ➢ 如何在不改变原来类模型的前提下,给类扩充一些方法?有2种方式 ● 继承 ● 分类(Categor ...

  2. OC基础--类的本质

    类的本质: 类的本质其实也是一个对象(类对象),只要有了类对象, 将来就可以通过类对象来创建实例对象 程序中第一次使用该类的时候被创建,在整个程序中只有一份.此后每次使用都是这个类对象,它在程序运行时 ...

  3. OC语言类的本质和分类

    OC语言类的深入和分类 一.分类 (一)分类的基本知识  概念:Category  分类是OC特有的语言,依赖于类. 分类的作用:在不改变原来的类内容的基础上,为类增加一些方法. 添加一个分类: 文件 ...

  4. OC 类的本质和分类

    一.分类 (一)分类的基本知识  概念:Category  分类是OC特有的语言,依赖于类. 分类的作用:在不改变原来的类内容的基础上,为类增加一些方法. 添加一个分类: 文件结构图: 在分类中添加一 ...

  5. 张超超OC基础回顾01_类的创建,申明属性,以及本质

    一. 类的声明和实现&规则 1.如何编写类的声明 以@interface开头 , 以@end结尾, 然后再class name对应的地方写上 事物名称, 也就是类名即可 注意: 类名的首字符必 ...

  6. OC类的本质,深入探讨,load方法和initialize方法

    1:类的本质:类也是一种类,可以叫做类类,类对象,类类型: 2:类和对象在内存中分配问题(注意区分类的对象和类对象的概念) 类对象在内存中只有一份,且只加载一次,类对象中存放了类中定义的方法: 而成员 ...

  7. OC类的本质及分类

    (一)类的本质 类对象(class object)与实例对象(instance object) 类本身也是一个对象,是class类型的对象,简称“类对象”. 在/usr/include/objc/ob ...

  8. OC-私有方法,构造方法,类的本质及启动过程

    总结 标号 主题 内容 一 OC的私有方法 私有变量/私有方法 二 @property 概念/基本使用/寻找方法的过程/查找顺序 三 @synthesize @synthesize概念/基本使用/注意 ...

  9. OC语言的面向对象—类和对象、方法

    1. 面向对象和面向过程思想 OC是面向对象的,C是面向过程的.面向对象和面向过程只是解决问题的两种不同思想 1. 面向对象和面向过程的区别 1) 以用电脑听歌为例子 a) 面向过程 ➢ 打开电脑 ➢ ...

随机推荐

  1. C#快捷键和注释

    C#注释    //单行注释    /*....*/快注释    ///说明注释,一般用于封装的属性和方法上   #region和#endregion折叠注释,可以将代码折叠 static void ...

  2. java测试框架整理

    Test: Junit4+Hamcrest 不多说了,就靠着两个 import static org.hamcrest.Matchers.equalTo; import static org.juni ...

  3. imx6 关闭调试串口

    需要关闭imx6调试串口,用作普通的串口使用. 参考链接 http://blog.csdn.net/neiloid/article/details/7585876 http://www.cnblogs ...

  4. 第二篇:白话tornado源码之待请求阶段

    上篇<白话tornado源码之一个脚本引发的血案>用上帝视角多整个框架做了一个概述,同时也看清了web框架的的本质,下面我们从tornado程序的起始来分析其源码. 概述 上图是torna ...

  5. EasyUI分页

    $("#tanModelBox1").css("display","none"); $('#dg').datagrid({ fitColum ...

  6. NSSet

    版权声明:本文为博主原创文章,未经博主允许不得转载. 一.NSSet的创建和初始化 创建一个空的NSSet集合:+ (void)set; 用数组来创建NSSet集合:+ (id)setWithArra ...

  7. 可爱的Python_课后习题_CDay−3 通过函式进行功能化

    1. 读取某一简单索引文件cdays−3-test.txt,其每行格式为:文档序号关键词,现须根据这些信息将它转化为倒排索引,即统计关键词在哪些文档中,格式如下:包含该关键词的文档数关键词 => ...

  8. iPhone CSS media query(媒体查询)

    iPhone5  iPhone6  iPhone6Plus iPad设备 media query(媒体查询)代码. iPhone < 5: @media screen and (device-a ...

  9. linux查看进程启动时间

    1. ps axu 2. 精确查看 for pid in $(pgrep httpd); do echo -n "${pid} " ; ps -p ${pid} -o lstart ...

  10. ElasticSearch作为Windows服务启动

           由于公司服务器用的Windows服务器,所以你懂得…… 直接下载elasticsearch中文发行版.下载地址是:https://github.com/medcl/elasticsear ...