续写某坑爹公司的教学笔记-OC语言整套Day01-06

来源:互联网 发布:javascript工资 编辑:程序博客网 时间:2024/06/10 09:36

【Day01】

OC语言面向对象


一、面向对象

Anything is Object.万物皆对象。


现实中的对象是一种客观存在,

程序中的对象是一片内存中的数据。

1.对象

现实中的对象学生       

有什么?姓名、年龄   

能干什么?学习   

1.对象       

计算机中的对象Student

属性(成员) age,name

方法(函数)study()


用解决现实中的问题的方法,来解决计算机问题。

2.类

设计(图纸)(梦想中)---努力实现--->楼(现实)

代码(文件)     ---执行加载--->内存(数据)

类                 ---实例化    --->对象

2.类

类是一种主观思想,是对我们需要解决问题的一种抽象,是创建对象的模型,就是类型,用户自定义类型。

对象就是具体的数据,计算机会把类->实例化->对象。

3.第一个面向对象程序

a.设计类Student 代码存在文件中,OC class。

一个类是由两个部分组成的 *.h文件和*.m文件

3.第一个面向对象程序

1).h文件 定义类的interface部分(声明)

@interface Student : NSObject

@property int age;//声明属性

-(void)study;//声明方法

@end

3.第一个面向对象程序

2).m文件 定义类的implemention部分(实现)

@implementation Student

//方法的定义、实现

-(void)study{

   NSLog(@"学生执行了study方法");

}

@end

3.第一个面向对象程序

b.类的实例化->对象

1)main.m文件中的->main函数(程序入口)执行程序

2)能过类发送alloc,通过一个类创建对象,通过stu变量,找到内存的对象。

3)可以向对象发送消息(函数),此时对象就会响应消息,执行方法。

4)对象如果有属性,对象.属性 = 值,给对象的属性赋值


创建一个Point2类,有横坐标x、纵坐标y,能显示位置show方法,创建两位置,并显示。

         


————————

【Day02】

二、方法

对象可以干什么,功能。

1.函数与方法有什么区别?

函数只是一个程序的代码段,与类无关系。

方法,类的一部分,代表对象可以干什么。

正常来讲,类必须实例化,方法才可以使用,实例方法,调用方法时,也叫做向对象发送消息。

.m:message

2.语法格式 语法格式与函数非常相似,但截然不同。使用方法时,在.h文件中声明,在.m文件中实现。

a.-(返回值类型) 方法名; //无参的方法eg:-(void)method;

b.-(返回值类型) 方法名:(参数类型)参数名;//有参的方法

eg:-(void)method3:(int)num;

c.-(返回值类型) 方法名:(参数1类型)参数名1 :(参数2类型)参数名2 :(参数n类型)参数名n;//多参的方法

eg:-(void)method4:(int)arg1 :(int)arg2;

注:":"符号也是方法名的一部分

method、method3:、method4::。

 d.*-(返回值类型) 部分方法名:(参数1类型)参数名1 

部分方法名2:(参数2类型)参数名2 

部分方法名n:(参数n类型)参数名n;

部分方法名起到提示作用,并不影响程序的执行

eg:-(void)printInfoWithAge:(int)age

andGender:(char)gender

andSalary:(double)salary;

三、实例变量

1.一个对象会有自己独特的数据和别的对象不同,这些数据会保存在一些特殊的变量中,这种变量叫实例变量。类的每个实例(对象)都有一份。

类                       对象(实例)(引用)

内存中没有       内存中有

成员变量           实例变量

成员方法           实例方法

2.用一个类,创建出一个对象,那么我们就说这个对象就是此类的实例,一个类可以有很多实例(对象),每一个实例都拥有一个和其它实例不同的数据,这些数据保存在实例变量中。


3.实例变量的声明,可以放在.h文件中,也可以放在.m文件,实例变量就变为私有的,只有当前对象才可以访问。

方法也是一样,放在.h文件中声明,公有方法。

方法在.h文件中没有声明,私有方法,是不合法的。


四、属性

1.在OC中,属性提供了setter和getter方法,本质上属性就是方法,属性的值是由实例变量来保存的。

2.属性的本质

一般三个部分组成

a.保存属性值的实例变量int _age;

b.setter和getter方法的声明与实现 

1.)setter方法:方法名:“set”+属性名并首子母大写+“:”+和属性类型一样的参数,无返回值。age

-(void)setAge:(int)newAge;

2.)getter方法:方法名和属性名一样,没有参数,返回值类型和属性类型一样。

-(int)age;

c.setter方法和getter方法的实现

setter方法的实现主要用来给属性赋值的

getter方法的实现主要用来读取属性值的

对象.属性 = 值;=>会自动调用setter方法

变量 = 对象.属性;=>会自动调用getter方法

stu.age = 18;//给属性赋值 setter

NSLog(@“age:%d",stu.age);

//取属性值 getter


3.声明式属性

a.定义实例变量

b.声明式属性

1).h文件中int属性类型 age 属性名

@property int age;

自动生成了settergetter

2).将属性与实例变量关联在一起 .m文件中

  @synthesize age = _age;

  c.属性的使用

引用.属性 = 值;=>会自动调用setter方法

变量 = 引用.属性;=>会自动调用getter方法

4.IOS5.0以后,属性的声明简化了

a.省去了实例变量声明,会自动生成实例变量名为_属性名的实例变量

b.声明式属性

1).h文件中int属性类型 age 属性名

@property int age;

自动生成了settergetter

2).将属性与实例变量关联在一起 .m文件中

  @synthesize age = _age;

  c.属性的使用

引用.属性 = 值;=>会自动调用setter方法

变量 = 引用.属性;=>会自动调用getter方法

5.***IOS6.0开始,声明式属性又简化

a.省

b.

1)保留

2)省@synthesize age = _age;

c.保留

6.属性的演变过程,如果你不满意,可以自己重写。

一、初始化方法

用来初始化对象的方法。

1.初始化方法的规则:

a.初始化方法都是以"init"开头的,无参的初始化方法叫"init",有参的都以"initWith..."开头。

b.初始化方法的返回值为"id"类型。(void*)

c.初始化方法的一般格式

super代表类的父类,[super init]是通知父类去做底层的初始化操作。

self代表当前对象或当前类,self就是当前对象的引用。(地址)

self = [super init];

if(self){//初始化,不一定成功,不成功值就为nil(NULL)

初始化对象的属性值...

}

return self;

d.初始化方法可以有多个,有参(一个参数、多个参数)、无参的。

e.执行无参的初始化方法

[[Student alloc]init]与[Student new]是等价的。

f.id类型

id类型是一种特殊的指针类型,类似void*,id类型其实就是一个指针变量,指向任何对象,在使用前必须类型转换。

Eg:

Student* stu = [Student alloc];

    id stu2 = [stu init];

    Student* stu3 = (Student*)stu2;

等价于:Student* stu = 

[[Student alloc]init];

[stu3 study];

二、实例方法和类方法

1.只能通过实例调用的方法叫实例方法。"-"

2.只能通过类调用的方法叫类方法。”+"

3.实例方法与类方法区别

a.实例方法与实例有关系的,所以实例方法可以调用、读取实例中的实例变量或属性。

b.类方法与实例无关系的,所以类方法不可以调用、读取实例例中实例变量和属性。

c.在类方法中可以创建对象,当然访问该对象的实例变量和属性。

三、工厂方法

生产(创建)对象的方法,叫工厂方法。

类中经常会出现一些工厂方法,其目的是为了方便创建对象。

规则:

1.工厂方法一定是类方法

2.工厂方法返回id类型,因为要返回一个刚创建好的对象类似初始化方法。

3.工厂方法的方法名一定以类名开头,注意去除了前缀和首字母要小写。


1.创建一个Point2类,有横坐标x、纵坐标y,能显示位置show方法,创建两位置,并显示。

(重构,属性,初始化方法(无参、有参),工厂方法(无参、有参)。

2.创建TRPerson类,有age、sex、salary,能显示信息的普通方法show,创建两个人。(重构,属性,初始化方法(无参、有参),工厂方法(无参、有参)。


————————

【Day03】

四、self关键字

代表当前对象或者当前类。

1.在实例方法中的self,通常来讲就是代表当前对象。

2.在类方法中的self,通常来来讲就是代表当前类。

五、编程规范

1.标识符

给变量、函数、类、方法、常量等起名字。

a.必须以_和字母开头

b.只能包含数字、_和字母

c.不能与关键字冲突

d.大小写敏感

e.长度是不限的

2.命名规范

a.类、分类、扩展、协议等类型起名时,一般加前缀(2~3个字母组成),并且每个单词的首字母大写。

b.驼峰标识:如果标识符由多个单词组成,每个单词的首字母大写。

c.属性、方法、变量的首字母小写,其后的每个单词的首字母大写。

d.常量一般大写,单词之间"_"隔开。

数字和字符是常量外,

const int MAX_NUM = 10;//常量

3.OC特有的代码风格

a.无参的初始化方法,"init"命名,有参的以"initWith … "开头。eg:

[[TRStudent alloc]init];

[[TRStudent alloc]initWithAge:18 andSex:'M'];

b.工厂方法,以小写的类名开头,有参的工厂方法,"小写类名With"开头。

[TRStudent student];

[TRStudent studentWithAge:18 andSex:'M'];

c.其它 

一般方法的方法名不能以new开头,new开头的方法基本上是用来创建对象的。

4.补充

a.代码的结构性,一定要缩进。

(command(win)+a全选,control(ctrl)+i自动代码缩进)

b.当一个方法比较长时,可以用空行的方式,将方法分成几个模块。

六、内存管理

1.进程空间

代码区:只读。

*堆:自己创建、自己回收释放,对象是保存在堆区的。

全局区:进程启动时分配,进行结束时释放。

栈:局部变量,自动创建、自动释放空间

内存管理:主要对堆内存进行管理,所谓的管理,内存的分配(创建)和释放(回收)。

2.IOS的内存管理方式

RC:Reference(引用)Counting(计算器)

a.MRC Maual手动

b.***ARC Automatic自动

3.MRC(手动内存管理)

a.每个对象都有自己的引用计数器,引用计数器是用来计算对象被引用的次数。

b.创建对象时(alloc、new),此时通知引用计数器为1 。

c.当你需要使用一个别人创建好的对象时,为了防止在使用此对象期间别人释放了这个对象,我们要将此对象的引用计数器加1(程序员通知引用计数器),只要给对象发送retain消息,引用计数器就会加1.

d.当你使用的对象不再使用时,你有责任通知引用计数器减1,发送release消息。

e.当对象的引用计数器为0时,说明已经没有任何引用指向对象,对象就会被系统自动销毁,系统销毁对象之前,会自动向对象发送一条消息"dealloc"消息,对象所占的空间就会被释放[super dealloc],千万不要自己去调用dealloc消息。

f.可以使用"retainCount消息",查看当前引用计数器的值。

g.当你指向的对象,不再使用时,如果忘了发送release消息,内存泄漏。(资源浪费)

h.当引用指向对象,已经不存在了,继续向对象发送消息,会发生问题,异常、crash

i.没有相应内存空间的指针,野指针。

j.会使用空指针,解决野指针问题,而在OC中,向空指针发送消息,是不会报错的。stu = nil;(C语言中 stu = NULL)


1.声明->类 

TRCpu TRMEM TRComputer(TRCpu TRMem)

初始化方法 工厂方法

2.使用->类实例化对象

向对象发送消息.结果屏幕输出结果

3.内存管理MRC


————————

【Day04】

二、autoreleasepool 自动释放池

1.池 节约空间 节资源 "共享"。

2.通过自动释放池来管理对象,只需要一个自动释放池,可以管理很多对象,当自动释放池结束的时候,会自动向池中的每个对象都发送release消息。

3.自动释放池是可以嵌套的,会先释放里面的,再释放外面的。

4.工厂方法通常都实现了发送autorelease消息。

三、面向对象的三大特征:封装、继承、多态

1.封装

封装属性和方法放在一个对象中,只给外界公开访问的接口,而且把具体实现隐藏起来。主要目的增加可读性、可维护性、可扩展性。

在OC中,把需要公开的属性、方法定义在声明中,.h文件中interface部分,而把不需要公开的属性、方法定义在.m文件中implementation部分,隐藏起来。

封装的好处:

1)代码结构更清晰

2)可以和第三方合作,但又保护了源代码,避免泄漏。

2.OC中实例变量的处理:

一般情况下,实例变量是不能公开的,所以实例变量应用定义在implementation部分(私有的),除非你需要直接在子类中访问,可以定义在interface部分,可以使用以下语法声明实例变量,来控制实例变量的访问范围。

a.变量的访问范围:

@public 可以在任意位置访问

@package 可以在包内部访问,一个项目一定是在同一个包下。

@protected 可以在本类内部和子类内部访问

@private 只可以在本类的内部分访问

b.默认实例变量修饰符:@protected

c.可以通过"->"可以访问实例变量(但不推荐),通过.语法(属性)来访问实例变量。

3.封装中的方法

a.如果.h文件中,未声明方法,此方法就是私有的,在其它文件中访问该方法是不合法的(必须不能访问)。

b.如果.h文件中,声明方法,此方法就是公有的,在其它文件中可以访问该方法的。

4.继承

a.概念

继承是一种代码复用技术,是类与类之间的一种关系。

A类继承B类,A类中就直接拥有B类中的属性和方法。我们就把A类叫B类的子类(派生类),把B类叫做A类的父类(基类)。

4.继承

b.继承方式

单继承

一个类只能继承一个父类。 爷<-爸<-你

OC Java C#

多继承

一个类可以有多个父类

C++

4.继承

c.继承的语法

@interface 类:父类 

(所有类都继承于NSObject)

@end

d.继承是一种关系

继承是类与类之间的关系,是一种"is a"关系。

狗是动物 狗:动物

e.方法的覆盖(重写)

子类对父类继承的方法不满意,可以在子类中重写父类的方法

1)方法名相同

2)参数类型相同

3)返回值类型相同

f.如果重写父类的方法,优先调用子类的方法,如果子类没有重写父类的方法,则调用父类的方法。


 一、继承的缺陷

1.提高了程序的复杂度,维护性和扩展性降低

2.破坏类的封装性

二、为什么使用继承

1.代码复用

2.制定规则

3.为了多态

三、组合和*聚合

复用代码更好的方法是组合和聚合,而不是继承。

组合和聚合也是类与类之间的"has a"的关系。

Computer has a cpu.

a.继承 一个对象

b.组合 代码书写习惯

优点:保留了封装性、操作便利 缺点:灵活度不够。

生命周期:Cpu和Computer封装性是独立的,生命周期是一致的,一起存在,一起销毁。高耦合(依赖)在一起。

c.*聚合

保留封装性 

优点:灵活度高 缺点:操作欠佳

生命周期:Cpu和Computer生命周期不一致,低耦合,方便Cpu的替换。两个对象,各过各的。

————————

【Day05】

四、多态

1.概念

多种形态,引用的多种形态。

对于一个引用变量,可以提向任何类的对象

对于一个父类的引用(类与类之间有一种关系,继承关系),可以指向子类,也可以向本类,指向的类型不同。当通过此引用向对象发送消息,调用的方法是不同的,此时方法的调用就是多态。

a.类与类之间有关系,继承关系。

b.父类的引用可以指向子类的引用,或者本类的引用。

c.父类的引用指向子类的对象,发送消息,调用的是子类对象的方法。

父类的引用指向本类的对象,发送消息,调用的是本类对象的方法。

2.编译期类型和运行期类型

a.在多态下,父类的引用可以指向子类的引用,当编译的时候,编译器无法确定指向的对象是什么类型,所以编译器会将引用当做父类类型引用编译检查。

b.在调用方法时,却是子类对象。(子类类型创建的空间)。


总结:TRAnimal* animal=[[TRDog alloc]init];

编译时,把TRDog类型当成TRAnimal类型编译。

[animal eat];

运行时,调用的是TRDog类型的对象。


3.多态可以用在参数,参数多态

4.多态可以用在返回值类型,返回值多态 工厂方法

5.多态可以用在数组上


————————

【Day06】

OC Category分类

分类就是类的补充和扩展部分

补充和扩展的每个部分就是分类

分类本质上是类的一部分

分类是给特定类添加能力


分类的定义

分类也是以代码的形式保存在文件中

分类文件命名 主类类名+分类类名

分类文件也分为*.h文件和*.m文件

*.h文件存放分类的声明部分内容

@interface 主类类名(分类类名)

//添加方法声明

@end

.m文件存放分类的实现部分内容

@implementation 主类类名(分类类名)

//添加方法实现

@end

分类中是不可以创建实例变量的,自然也不可以创建属性。

在分类中是可以访问主类的属性,但不可以访问主类的实例变量。

分类的实现步骤:

1.创建分类

2.调用分类中的方法

3.#import 分类


分类的使用

分类可以给一个自定义类添加功能

分类还可以给一个系统类或第三方类添加功能


二、扩展(延展)

1.概念

扩展其实就是分类的一种特殊形式,扩展是没有名字的。

2.使用方式

a.扩展中可以声明实例变量,所以可以声明属性

b.扩展通常定义在文件的.m中,不能分开。

c.扩展是用来声明私有的属性和方法

区别:

分类:是不可以声明实例变量,通常是公开的,文件名通常为:"主类类名+分类类名.h"

扩展:是可以声明实例变量,是私有的,文件名通常为:"主类类名_扩展标识.h",注意扩展没有名的。


三、协议

1.概念

协议就是规则,定义一个协议就相当于制定规则。

OC中类可以遵守协议,遵守了一个协议的类相当于拥有了一种能力。

2.语法

@protocal协议名

@required声明必须遵守的属性和方法

@optional声明可选(可以)遵守的属性和方法

默认 @required

@end

3.一个类遵守一个协议

a.@interface类名(分类类名):父类名<协议名>

b.实现协议中声明的方法

4.使用协议类型的引用指向实现了协议或者遵守了协议的对象

id<TRProtocol> p = [[MyClass]init];

[p …];可以向协议的引用发送消息,只能发送协议要求的消息。

5.协议的继承

协议的继承相当于协议的合并。

子协议      父协议

@protocol TRTarena2 <TRTarena>

-(void)learn;

   @end

6.一个类可以同时遵守多个协议,协议之间使用","分隔符分开。

    @interface TRStudent : NSObject<TRTarena,TRTarena3>


7.协议的使用和多态相类似,可以用于数组、参数、返回值类型,只不过多态返回的对象,一定要有继承关系,协议类型返回的对象,一定要有遵守协议或实现协议。


四、内存管理ARC自动引用计数器管理

1.ARC IOS5.0以后才支持,IOS7.0以后,强制使用ARC。

2.ARC "Automatic" Refercences Counting

3.原理

       依然使用引用计数器来管理内存,只是引用计数器的操作方式不同,由程序员发送消息转换为“编译器”帮我们自动发送消息,会在合适的位置自动加入retain、release、autorelease消息来进行计数管理,ARC是一种编译期语法。

4.使用ARC

a.在ARC中,程序中不能出现retain、release、autorelease…

b.在ARC中,程序不能在dealloc方法中显示调用父类的dealloc方法,一切在MRC中和内存相关的操作,ARC中都不能使用。

5.强引用

a.在程序中定义的引用,默认为强引用,所谓的强引用指向一个对象时,对象的引用计数器会自动加1,当引用超出作用域"{}",对象的引用计数器就会减1.

b.定义强引用

  __strong TRStudent* student = [TRStudent alloc]init];

c.当一个对象被引用指向时,此对象会隐式的retain一次,当强引用超出作用域时,指向的对象会隐式的发送release消息一次。

d.引用在使用的时候,会根据作用域的范围,自动做加1或减1的操作。

6.弱引用

a.定义弱引用

__weak TRStudent* student;

b.仅仅就是指向对象,但不会隐式的发送retain消息,出了作用域也不会发送realse消息。

c.XXX当一个弱引用指向的对象,未销毁时,向对象发送消息,此弱引用会自动的变为强引用。(xcode4.x)版本

d.当一个弱引用指向的对象被销毁时,弱引用本身会自动的赋值为空。(nil)

  zeroing weak reference

四、内存管理ARC自动引用计数器管理

7.定义属性的时候,内存管理的描述

@property(nonatomic,strong)…;

@property(nonatomic,weak)…;


重构ARC Student与Book的故事。


8.其它修饰关键字

@property(nonatomic,unsafe_unretained)int age;

a. unsafe_unretained等同于"assgin",功能和__weak几乎一样,唯一不同,没有"zeroing weak reference",通常使用在基本数据类型。

b.__autoreleaseing 用在方法的返回值,将返回值的对象放入到自动释放池中。

+(id)student{

__autoreleaseing TRStudent* student = [[TRStudent alloc]init];

    return student;

}

9.dealloc方法

      a.在ARC下,dealloc方法不允许调用父类的dealloc方法,当然也不允许向任何对象发送release消息,所以说dealloc方法几乎无用。

       b.在一些特殊情况下需要重写dealloc方法。

  1)在类中使用了C语言中的函数malloc分配内存。

  2)在类中使用了C++语言中的函数new等方式创建内存空间。

  此时需要在dealloc中对这些特殊的空间进行释放。

10.声明引用自动置空

a.在ARC下,如果定了一个引用没有赋值,编译会自动的初始化设置引用为空值。TRStudent* student;

b.为了尊重C语言的规范,基本数据类型没有初始化值,依然是垃圾值。

11.MRC和ARC混用

a.把MRC的代码转换成ARC的代码(手动)

    retain=>strong

    release、autorelease、[super dealloc]删除掉。

b.xcode提供了自动将MRC转换成ARC的功能。

  菜单栏(Edit)->Refacotor(重构)->Convert to Objective-C ARC

c.在ARC项目中继续使用MRC编译的类

    在编译选项中标识MRC文件即可

    "-fno-objc-arc"

d.在MRC项目中继续使用ARC编译的类

    在编译选项中标识MRC文件即可

    "-fobjc-arc"



0 0
原创粉丝点击