美文网首页
OC重学第三天

OC重学第三天

作者: 火之夜工作室 | 来源:发表于2017-05-26 14:05 被阅读23次

通过上篇文章,我学习了OC 的几个比较容易混淆的关键字,在讨论 self= [super init] 的方法的时候,想到了还涉及到SEL 所以开篇第一个就学习一下SEL ,不过今天主要学的是OC 特有语法

一 . SEL

1 . SEL 全称叫做 selector 选择器

  SEL 是一个数据类型,所以要在内存中申请空间存储数据.
  SEL 其实是一个类 SEL 对象是用来存储1个方法的
  可以理解@selector(),方法选择器.于是乎就可说是C 中的指针函数.而在OC里不能用指针函数,所有就只能搞一个@selector 来去了
  他的结果的SEL类型,用assgin修饰.去取方法的编号(函数地址)

2. 类是以Class对象的形式存储在代码段中.

 还要将方法存储的 类对象之中,怎么江方法存储在类对象中.
 1. 先创建一个SEL 对象.
 2. 将方法的信息存储在这个SEL对象之中
 3. 再将这个SEL对象作为类对象的属性

3. 拿到存储方法的SEL对象

  1. 因为SEL是一个typedef类型的 在自定义的时候已经加*了.所以我们在声明SEL 指针的时候 不需要加 * 
  2. 取到存储方法的SEL 对象
     SEL S = @selector(方法名)

4. 调用方法的本质

[s sayHi];
内部的原理
 1. 先拿到存储sayHi方法的SEL对象,也就是拿到存储sayHi方法的SEL 数据.SEL消息
 2. 将这个SEL消息发送给 s对象
 3. 这个时候,s对象接收到这个SEL消息以后 就知道要调用方法
 4. 根据对象的ISA指针找到存储类的类对象
 5. 找到这个类对象以后 在这个类对象中去搜寻是否有传入的SEL数据相匹配的 如果有 就执行 , 如果没有再找父类 直到NSObject .

5 . 手动为对象发送SEL消息

  1. 先得到方法的SEL数据
  2. 将这个SEL消息发送给s对象
     调用对象的方法 将SEL 数据发送给对象
     - (id)performSelector:(SEL)aSelector;
     Person *p1 = [Person new];
     SEL s1 = @selector(sayHi);
     [p1 performSelector:s1]; 与 [p1 sayHi]效果是完全一样的.

 3. 调用1个对象的方法有两种.
   1. [对象名 方法名];
   2. 手动的为对象发送SEL消息.

其实这个调用的本质 就是 消息机制
我也是查看了大神的blog 才慢慢的对消息机制有了一点认知 话不多说 好文章当让与 火友 一起分享 <a href="http://yulingtianxia.com/blog/2014/11/05/objective-c-runtime/" target-"_blank">火之叶</a>

二 . 点语法

1 . Java C# 对象可以使用点语法来访问对象的成员变量

OC中也有点语法. OC 中也可以使用点语法来访问对象的属性.但是OC的点语法和Java C#是完全不一样的
OC 的对象如果要为属性赋值或者取值 就要滴啊用对应的getter 或者 setter

2. 使用点语法来访问对象的属性

语法
   对象名.去掉下划线的属性名;
   这个时候就会将@"火之叶"赋值给p1对象的_name属性
   p1.name = @"火之叶";
   NSString *name = p1.name; 把p1对象的_name 属性的值取出来
   ```
##3. 点语法的原理
    1). 当使用点语法赋值的时候. 这个时候编译器会将点语法转换为调用setter方法的代码.

      对象名.去掉下划线的属性名 = 数据;
      转换为:
      [对象名 set去掉下划线的属性名首字母大写:数据];
      p1.age = 10;
      [p1 setAge:10];


  2).当使用点语法取值的时候.这个时候编译器会将点语法转换为调用getter方法的代码.
      对象名.去掉下划线的属性名;
      转换为:
      [对象名 去掉下划线的属性名];
      int age = p1.age;
      int age = [p1 age];


##  4.注意.

  1). 在getter和setter中慎用点语法,因为有可能会造成无限递归 而程序崩溃,
  2). 点语法在编译器编译的时候 会转换为调用setter getter方法的代码.
      p1.name = @"jack";
      [p1 setName:@"jack";
      NSString *name = p1.name;
      NSString *name = [p1 name];
      如果我们的setter方法和getter方法名不符合规范 那么点语法就会出问题.
  3). 如果属性没有封装getter setter 是无法使用点语法的 
      因为点语法的本质是getter setter方法.

#三 .  统一的介绍
## 1. @property
   Xcode4.4之前
   @property: 只生成getter、setter方法的声明.
   @synthesize: 生成私有属性.并生成getter、setter方法的实现.
   Xcode4.4开始.
   @property增强: 
   1). 自动生成私有属性.
   2). 自动生成私有属性的getter setter方法的声明和实现.

##2. 编译检查与运行检查
   编译检查: 
   通过1个指针去访问对象的成员的时候,编译判断可以不可以的准则: 指针的类型当中是否有这个成员.
   运行检查:
   在程序运行的时候,通过1个指针去访问对象的成员之前,还会检查指针所指向的对象中是否真的有这个成员.


##3. 万能指针(NSObject、id). instancetype
   NSObject和id 它们都是万能指针,可以指向任意的OC对象.
   NSObject指针访问对象的成员的时候,编译器会做编译检查.
   id指针调用指针指向的对象的方法的时候.编译器不做任何检查 直接通过.
   id指针的缺点: 不能使用->访问属性 也不能使用点语法.
   instancetype: 只能做为方法的返回值.代表返回当前类的对象.


##4. 动态类型检测 反射
   1). 判断指针指向的对象中 指定的方法是是否可以调用.
   2). 判断类方法是否可以调用.
   3). 判断对象是否为指定类的对象或者子类对象.
   4). 判断对象是否为指定类的对象.
   5). 判断指定的类是否为另外1个类的子类.

##  5. 构造方法.
   1). new是1个类方法. 创建对象初始化对象返回对象.
   2). new方法的内部其实就是 alloc init
   3). init方法就叫做构造方法. 初始化对象
   4). 重写init构造方法.     
   5). 自定义构造方法.
  如果你想要调用init默认的构造方法.那么new可以. 也可以使用alloc init
  如果你像要调用自定义的构造方法.这个时候就必须先alloc 再调用自定义的init

相关文章

  • OC重学第三天

    通过上篇文章,我学习了OC 的几个比较容易混淆的关键字,在讨论 self= [super init] 的方法的时候...

  • OC重学第一天

    一 . Objective-C基础语法 二. OC 与 C 的对比 三 . 类与对象 1 . 类与对象的区分 2 ...

  • OC重学第二天

    一. 类方法 OC 中方法分为两种.对象方法/实例方法如果想要调用对象方法必须要创建对象,通过对象来调用类方法.类...

  • iOS重学之探究OC对象的本质

    写在前面 苹果官方源码下载:opensource.apple.com/tarballs -> 搜索objc/4 -...

  • 重学iOS——1.从C角度看OC

    面向对象 面向对象的编程思维,简而言之就是:一切皆对象。面向对象的语言区别于C语言(面向过程),C语言是按照代码的...

  • 感受英国的教育

    英国的教育注重学生自主的发展,注重学生兴趣的培养,注重学生实际能力的锻炼。为此学校教育的各个环节都注...

  • 知识分子学佛的通病

    能知不能行 重学理不重实证

  • 重学iOS系列之底层基础(一)OC对象的本质

    导读 在开发过程中,是否有疑惑过,我们创建的OC对象本质到底是什么?实例对象在内存中是怎么存储的?对象在程...

  • 重学PHP

    Run your application: Read the documentation at https://s...

  • 重学pet

    刚知道这一期的觉知课程主题是沟通时,顿时就产生了不去的念头,可是因为怕麻烦,还是决定跟下去。在课堂上,明显觉得自己...

网友评论

      本文标题:OC重学第三天

      本文链接:https://www.haomeiwen.com/subject/bfjoxxtx.html