OC语言·笔记二

摘要:
1) 生成实例变量以存储属性值2)生成访问器(setter和getter方法)以修改和访问属性值1.2您在实际开发中知道的事情:属性的getter和setter方法都可以由程序员自定义。编译器添加getter方法和实例变量b。如果仅自定义getter方法,则编译器添加setter方法和示例变量c。如果自定义getter和setter,
1. 属性(Property)和实例变量(instance variable)

1.1 当定义一个属性时,本质上是在干什么(编译器在帮我们干什么):

1) 生成实例变量用来保存属性的值

2) 生成访问器(setter和getter方法)用于修改和访问属性的值

1.2 实际开发中知道的事:

1) 只读属性:只能读取值,不能修改值。这种属性只生成getter方法,不生成setter方法。

2) 计算属性:没有对应的实例变量,属性的值经常是通过计算得到的。在swift中,这种属性叫计算属性。

3) 自定义setter/getter:一个属性的getter方法和setter方法都可以由程序员自定义。当程序员不满意编译器生成的访问方法(setter/getter)时,可以自定义。

a.如果只自定义了setter方法,编译器补上getter方法和实例变量

b.如果只自定义了getter方法,编译器补上setter方法和实例变量

c.如果自定义了getter和setter,编译器就会认为你不需要实例变量,不会补上实例变量

1.3 属性的其他细节

1) 如果getter和setter都自定义了,实例变量就不会自动生成,但如果需要实例变量,可以使用属性合成器synthesize指定实例变量:

在implementation中,加一句: @synthesize 属性名 = 实例变量名;

//使用属性合成器指定属性所对应的实例变量

@synthesize age = _age;//此时编译器会生成_age这个实例变量

2) 如果getter方法和setter方法不需要编译器生成,可以在.m文件中使用 @dynamic 来要求编译器不要生成访问方法。

应用场景:一般会在CoreData的代码使用这种方式。

@dynamic 属性名; //不要生成此属性的setter和getter

特殊属性,编译器不生成setter和getter,程序在运行时才通过特殊手段获得setter和getter方法。

经常会在CoreData的代码中看到这种情况。(如:属性的值需要获取后台数据库读到) 

3) 实例变量的访问范围

  • 在接口部分(.h文件中)定义的实例变量默认(@protect)可以在本类的内部,及子类的内部访问。
  • 在.m文件中定义的实例变量,只能在本类的内部访问。其实地方都访问不了。都是私有的。
  • 在接口部分(.h文件中)定义的实例变量如果真希望别人也访问,可以用@public将其公开。我们不建议这么做。

//实例变量的访问修饰符

{

@protected //默认是保护,可省略不写

    int protectedVar;//默认是保护的,只能在本类内部及子类内部访问

@public

    int publicVar;//公开的实例变量,一般不这样做

@private

    int privateVar;//私有的实例变量,只能在本类的的内部访问

}

2. 初始化方法(构造方法)

2.1 概念

一种特殊的方法,专门用于初始化对象。

在OC中init开头的方法,我们称之为初始化方法(构造方法)。

     构造方法的用途:用于初始化一个对象,让某个对象一创建出来就拥有某些属性和值

[[类型 alloc]init]; //init就是初始化方法

2.2 怎么写

任何一个对象,都默认有一个初始化方法:init,是从NSObject类中继承来的。

如果程序员不满意继承来的init方法,可以自己重写。

怎么写?固定写法:

1) 必须先调用父类的初始化方法,并将返回值赋值给self(self是指向当前对象的引用)

2) 如果父类初始方法调用成功,此时给对象中的属性赋初始值。初始化对象的主要目的就是给属性赋值。

3) 方法结束时,必须返回当前对象(self).

注意: 初始化方法返回空代表初始化失败

    OC语言·笔记二第1张

2.3 初始化方法的注意事项

1) 初始化方法可以有多个,初始化对象时可以选择的调用。

2) 当一个类没有提供任何初始化方法时,也有init方法。从父类继承来的init方法会将所有的属性初始化为0.

3) 关于空(nil),OC中表示空指针的字面值是nil,相当于C语言中的NULL

    OC语言·笔记二第2张

4) 返回值类型instancetype(instancetype会自动把返回值类型变成具体的类型)

  • 从iOS7 SDK开始, 初始化方法,以及创建对象的工厂方法,其返回值全部使用instancetype类型。
  • instancetype会自动根据方法的返回对象识别返回类型(返回什么类型的对象instancetype就变成什么类型,instancetype会自动知道返回值的类型),instancetype只能出现在返回值类型上。

2.4 id类型

id类型是动态类型,当程序运行到这句话时,才知道这句话某一个变量是什么类型。

id类型定义的变量,它里面存的这个值的类型不确定。运行时才确定,编译时也不确定。也叫万能指针。

  • id类型是万能类型,有风险;id类型只针对对象类型,不针对基本类型;id类型只能指向对象。是一种通用对象类型!
  • id类型的变量其实是一个可以指向任何类型对象的引用(指针),类似于C语言中的void*(万能指针)

如:id r = [[TRPerson alloc]init];

id类型被定义为指向NSObject子类的实例对象的指针

double d = 10.5;

id a = &d;//ERROR

id是一个指针,但在使用时无需加*

id stu = nil;

id类型的变量可以出现在变量能出现的任何地方,比如方法的参数上,返回值类型上,或直接定义局部变量等。

使用id类型的好处:可以指向任何对象; 坏处:编译器失去了对类型的检查。

 

总结:id和instancetype的区别

  1. id可以做方法的返回值类型,方法的参数类型,还可以直接声明变量,或定义成属性
  2. instancetype只能做初始化方法和工厂方法的返回值类型,不能在方法的参数等地方使用instancetype

instancetype类型比id类型好一点:因为instancetype会自动把它的返回值类型转换成它具体的类型。而id类型则是万能类型,带有一定的风险(还要做一些类型转换,多了一些步骤,性能和效率会低一点)。

3. 类方法(class method)

3.1 概念

1) 实例方法(instance method):

以"-"号开头的方法叫实例方法

必须通过实例(对象)去调用,向对象发消息会调用实例方法

2) 类方法

以"+"号开头的方法叫类方法

必须通过类去调用,向类发消息就会调用类方法

如果一个方法的具体实现与对象无关(即不会使用对象的属性或实例变量),就可以考虑写成类方法!!!

注意:

类方法中不能使用类的成员变量!(即在类方法中不能直接访问对象的东西)

在实例方法中可以使用类的成员变量!

3.2 为什么使用类方法

1) 类方法的调用比较方便,不用创建对象就可以

2) 如果有一个方法,不需要使用某个对象属性,那么可以考虑写成类方法,为了方便调用。

3) 经常使用类方法来创建对象,这种类方法被称为简单工厂方法,或直接叫工厂方法

在类方法中,不能直接访问属性和实例变量,也不能直接调用实例方法。(与对象有关的操作在类方法中都不能用!)

类方法属于整个类,和具体的对象无关,所以对象的属性和实例变量不能在类方法中访问。

    

4. 工厂方法(Factory Method)

一个类为了方便创建对象,提供一个类方法返回一个新对象,这个类方法就叫工厂方法。是简单工厂模式的具体体现。

工厂方法就是把alloc方法和init方法合并写成一个方法。

工厂方法的方法名格式:类名WithXXX…开头(类名首字母小写)

TRPoint *p1 = [[TRPoint alloc]initWithX:1 andY:2];//一般创建对象

TRPoint *p2 = [TRPoint pointWithX:2 andY:4];//用工厂方法创建对象

   OC语言·笔记二第3张

5. 单例模式(Singleton):就是单个实例的意思。是一种特殊的工厂方法。一个类只允许创建一个对象。

什么是单例模式:

1)主要用于做应用程序的资源共享控制

2)只能生成唯一的对象

3)利用类方法来创建和访问对象

单例模式的原理:

1)类中定义一个实例(static全局变量)

2)类中定义一个类方法作为单例方法

3)在单例方法中如果类中定义的实例为空,则创建该类的实例;否则返回此实例。

     OC语言·笔记二第4张

     OC语言·笔记二第5张

单例模式的好处:节约资源、提高效率、统一管理。

NSNotificationCenter 通知中心 也是一个单例类

UIApplication(代表一个应用程序,App是唯一的) 就是一个单例类

   OC语言·笔记二第6张

OC语言·笔记二第7张

设计模式:(经典23种设计模式)

解决一个典型问题的最佳方案。

工厂模式: 简单工厂模式(工厂方法)   工厂模式  抽象工厂

简写方式:[TRPoint new];相当于写[[TRPoint alloc]init]; (一个意思的不同写法)

[[TRPoint alloc]init]这种写法方便重写初始化方法(init..),[TRPoint new]这种写法不能。

免责声明:文章转载自《OC语言·笔记二》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇安装redis及异常处理Nginx进行流量copy到测试环境下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

unity3D shader学习

网络信息汇总   unity内部阴影的使用 阴影的投射只要有shadow caster通道即可;阴影接受的计算: 方法1 1 #pragma multi_compile_fwdbase 2 #include “AutoLight.cginc” 3 SHADOW_COORDS(1) // put shadows data into TEXCOO...

Linux(Ubuntu)设置环境变量(转载)

http://blog.csdn.net/wumingxing0228/article/details/6050175 环境变量是和Shell紧密相关的,用户登录系统后就启动了一个Shell。对于Linux来说一般是bash,但也可以重新设定或切换到其它的 Shell。对于UNIX,可能是CShelll。环境变量是通过Shell命令来设置的,设置好的环境变...

JVM 详解

1 jdk  和jre 的区别     jre 石 Java 运行环境,只能运行 class 不能编辑 Java文件,不能dubug。  2  jdk下面的  bin/jconsole.exe 监控 一些内存,线程,jvm 。 3 Java 的 层级 ,以前我们关注的是三面 三次。jvm 是最下面一层    4 Java的  作者是  詹姆斯·高斯林   ...

Win32汇编_变量

Win32汇编_变量全局变量:全局变量的作用域是整个程序,Win32汇编的全局变量定义在.data或.data?段内,可以同时定义变量的类型和长度.格式是:变量名类型初始值1, 初始值2, …变量名类型重复数量 dup (初始值1, 初始值2, …)例:.data;全局变量的类型才可以用缩写wHour dw ? ;未初始化的word类型变量wMinute...

eclipse,sts怎么把多个微服务或者多个项目备份到码云的同一个仓库下进行管理

观前提示 第一部分:提交方法 第二部分:可能出现的错误和解决方法 第三部分:自己的尝试过程 -----------------------------------------------------------第一部分-------------------------------------------------------- 前提:无法在eclipse...

在ORACLE中存储过程变量名和表字段名相同

1.事件概述 今天再写存储过程使用变量没注意到问题,导致SQL执行缓慢,找了许久才发现哪里有问题。 2.发现问题 在存储过程中执行下图sql需要20秒左右,执行计划发现走了全表扫描,而在存储过程中相同的SQL不会有问题。 然后我单独把SQL拿出来跑,将变量名替换成真实数据,1秒就执行出来了,执行计划走了索引。 存储过程重新看了很久,是不是哪里有问题,变量...