C和OC对比
1.OC中主要开发在什么平台上的应用程序?
答:OC中新增关键字大部分是以@开头
2.OC中新增加了那些数据类型?
答:Block类型 指针类型(Class, id类型) 空类型 特殊类型(SEL, nil)
3.面向对象特性是什么?
答:继承性,封装性,多态性
4.import和#include有什么区别?
答:include是C语言的文件包含指令,不能防止文件重复导入和循环引用;
而import是OC中的文件包含指令, 能防止文件重复导入,不能防止循环引用。
5.printf和NSLog有什么区别?
答: NSLog会自动换行,在输出内容时会附加一些系统信息;NSLog和printf接收的参数不一样
6.Foundation有什么作用?
答:Foundation.h我们称之为主头文件, 主头文件中又拷贝了该工具箱中所有工具的头文件, 我们只需要导入主头文件就可以使用该工具箱中所有的工具, 避免了每次使用都要导入一个对应的头文件
面向对象基本概念
什么是面向对象?
答:对象是人们要进行研究的任何事物,从最简单的整数到复杂的飞机等均可看作对象,它不仅能表示具体的事物,还能表示抽象的规则、计划或事件。
面向对象和面向过程的区别?
答:1>面向对象是相对面向过程而言
2>面向对象和面向过程都是一种思想
面向过程 强调的是功能行为 关注的是解决问题需要哪些步骤
面向对象 将功能封装进对象,强调具备了功能的对象 关注的是解决问题需要哪些对象
面向对象特性
面向对象三大特性是哪些?
答:继承性,封装性,多态性
什么是封装?为什么要进行封装?封装的好处?封装的规范?
答:封装: 屏蔽内部实现的细节, 仅仅对外提供共有的方法/接口
原因:一个类把自己的成员变量暴露给外部的时候,那么该类就失去对该成员变量的管理权,别人可以任意的修改你的成员变量。 好处: 保证数据的安全性,将变化隔离
规范: 一般情况下不会对外直接暴露成员变量, 都会提供一些共有的方法进行赋值
成员变量都需要封装起来
类与对象
什么是对象?
答:对象是人们要进行研究的任何事物,从最简单的整数到复杂的飞机等均可看作对象,它不仅能表示具体的事物,还能表示抽象的规则、计划或事件。
什么是类?
答:具有相同特性(数据元素)和行为(功能)的对象的抽象就是类。因此,对象的抽象是类,类的具体化就是对象,也可以说类的实例是对象,类实际上就是一种数据类型。
类由几部分组成?
答: 类(Class) 一个类由3个部分构成 1.类的名称:类名 2.类的属性:一组包含数据的属性 3.类的方法:允许对属性中包含的数据进行操作的方法。
实例化对象调用哪个方法?实例化对象做了哪3件事?
答:实例化对象调用类方法new
1.给对象分配存储空间
2.初始化类中的实力变量
3.返回对象内存地址
类和对象的区别?
答:类是一个抽象的概念,它不存在与现实的时间/空间里,只是为所有的对象定义了抽象的属性与行为。 对象是类的一个具体它是实实在在存在的东西。
类是一个静态的概念,类本身不携带任何数据;当没有为类创建对象时,类本身不存在内存空间。
对象是一个动态的概念,每一个对象都存在着有别于其他对象的属于自己的属性和行为;
对象的属性可以随着自己的行为发生改变。
OC方法和C函数
OC方法和C函数的区别?
答: OC中的方法和C语言中的函数一样, 都是用来保存一段特定功能的代码
C语言中定义一个函数, 分为声明和实现,写在文件的任何位置(@interface 和 @end 之间除外)
OC中定义一个方法, 也分为声明和实现, 声明写在@interface中, 实现写在@implementation ,可以没有声明只有实现 C语言的函数分为内部函数和外部函数,OC中的方法也分为类方法和对象方法
函数属于整个文件;方法属于某一个类,方法如果离开类就不行
函数可以直接调用, 方法必须用对象或者类来调用
类方法和对象方法的区别?
答:0). 对象方法以-开头, 类方法以+开头
1). 对象方法必须用对象调用,类方法必须用类来调用
2).对象方法中可以直接访问属性(成员变量) ,类方法中不可以直接访问属性(成员变量)
3). 类方法和对象方法可以进行相互调用
geeter-setter方法
什么是setter/getter方法?setter/getter方法的书写格式?
答:setter方法就是给成员变量赋值的方法
格式: (1) setter方法一定是对象方法
(2) 一定没有返回值
(3) 一定以set开头, 并且set后面跟上需要设置的成员变量的名称去掉下划线, 并且首字母大写
(4) 一定有参数, 参数类型一定和需要设置的成员变量的类型一致, 并且参数名称就是成员变量的名称去掉下划线
getter方法就是获取成员变量值的方法
格式: (1) getter方法一定是对象方法
(2)一定有返回值, 而且返回值一定和获取的成员变量的类型一致
(3)方法名称就是获取的成员变量的名称去掉下划线
(4) 一定没有参数
成员变量以下划线开头有什么好处?
答:1.用于区分局部变量/全局变量/形参;2.方便程序编码, 提高编码效率
什么是只读属性?什么是只写属性?可读可写的属性?私有属性?
答:一个属性可以只有getter方法, 没有setter方法, 这种属性称之为只读属性。
一个属性也可以只有setter方法, 没有getter方法, 这种属性称之为只写属性。
如果既有setter方法又有getter方法, 那么这种属性称之为可读可写的属性。
一个属性也可以没有getter和setter, 这种属性称之为私有属性。
点语法
什么是点语法?点语法的本质?
答:如果给属性提供了getter和setter方法, 那么访问属性就又多了一种访问方式 , 点语法.
点语法的本质是调用了一个类的setter和getter方法
如何使用点语法?
答: 点语法是一个编译器的特性, 会在程序翻译成二进制的时候将.语法自动转换为setter和getter方法 如果点语法在=号的左边, 那么编译器会自动转换为setter方法
如果点语法在=号的右边, 或者没有等号, 那么编译器就会自动转换为getter方法
点语法注意事项?
答:点语法一般用于给成员变量赋值, 如果不是给成员变量赋值一般情况下不建议使用, 但是也可以使用
self关键字super关键字
1.如何使用self?
如果self在对象方法中, 那么self就代表调用当前对象方法的那个对象
如果self在类方法中, 那么self就代表调用当前类方法的那个类
总结:我们只用关注self在哪一个方法中 , 如果在类方法那么就代表当前类, 如果在对象方法那么就代表”当前调用该方法的对象”
self有哪些注意事项?
答: (1)self会自动区分类方法和对象方法, 如果在类方法中使用self调用对象方法, 那么会直接报错
(2)不能在对象方法或者类方法中利用self调用当前self所在的方法
self的有哪些使用场景?
答: 可以用于在对象方法之间进行相互调用 可以用于在类方法之间进行相互调用 可以用于区分成员变量和局部变量同名的情况
2.什么是super?
super是个编译器的指令符号,只是告诉编译器在执行的时候,去调谁的方法.
怎么使用super?
答:super在类方法中, 一定会调用父类的类方法
super在对象方法中, 一定会调用父类的对象方法
可以利用super在任意方法中调用父类中的方法
super使用场景?
答:子类重写父类的方法时想保留父类的一些行为
私有变量和私有方法
什么是私有变量?什么是私有方法?
私有变量:写在@implementation中的成员变量, 默认就是私有的成员变量, 在其它类中无法查看, 也无法访问 私有方法:在@implementation中定义,只能在本类中访问
继承和复合
继承:一般在创建一个新类的时候,通常需要根据它与现有类之间区别来定义。使用继承可以定义具有父类所有功能的新类,并且新类可以拥有父类所有的属性和行为,同时也可以定义自己专属的属性和行为,这就是类的继承。OC语法只支持单根继承,即一个类只能有一个父类。
复合:所谓的复合就是在一个对象当中引用另一个对象的策略,一般被引用的对象是作为引用对象的一部分而存在,这样对象的结构更加灵活多变。例如:可以使用复用来实现一个汽车car模型的结构定义,一辆汽车有一个引擎,同时对应四个汽车轮胎。
什么叫方法重写?重写后是以什么顺序调用方法的?
答:如果子类中有和父类中同名的方法, 那么我们称之为方法重写。
注意: 继承中的方法调用顺序, 如果自己有就调用自己的, 如果自己没有就调用父类的
“方法的调用顺序, 先自己再父类, 如果父类中没有再爷爷类, 如果爷爷类再没有就找爷爷的爸爸类如果一直找到NSObject类都没有找到, 那么就会报错。 注意:在继承中方法可以重写, 但是属性(成员变量)不能重写
方法重写的使用场景?
答: 当从父类继承的某个方法不适合子类,可以在子类中重写父类的这个方法。
什么是多态?程序中是怎么体现多态的?
答:多态就是某一类事物的多种形态
体现:父类指针指向子类对象
多态的条件是什么?多态的优点是什么?
答:条件:1)有继承关系 2)子类重写父类方法 3)父类指针指向子类对象
优点:提高了代码的扩展性,复用性
description方法
只要利用%@打印某个对象, 系统内部默认就会调用父类的description方法,description方法的默认实现是返回类名和对象的内存地址,这样的话,使用NSLog输出OC对象,意义就不是很大,因为我们并不关心对象的内存地址,比较关心的是对象内部的一些成变量的值。因此,会经常重写description方法,覆盖description方法的默认实现
重写description方法注意点?
答:如果在description方法中利用%@输出self会造成死循环
建议: 在description方法中尽量不要使用self来获取成员变量,因为如果你经常在description方法中使用self, 可能一不小心就写成了 %@, self: 1 - (NSString *)description {
2 return [NSString stringWithFormat:@"%@", self];
3 }
这样就会成为死循环
property和property修饰符
1.@porperty是一个编译器指令,可以使用@porperty来代替getter/setter方法的声明,也就是说我们只需要写上@porperty就不用写getter/setter方法的声明
2.使用property增强后,什么时候要重写getter/setter方法?
答:使用property增强,只会生成最简单的getter/setter方法的声明和实现, 并不会对传入的数据进行过滤;
如果想对传入的数据进行过滤, 那么我们就必须重写getter/setter方法
3.重写getter/setter方法有哪些注意点?
答:如果重写了setter方法, 那么property就只会生成getter方法;
如果重写了getter方法, 那么property就只会生成setter方法;
如果同时重写了getter/setter方法, 那么property就不会自动帮我们生成私有的成员变量
4.@property语法中readonly/readwrite,atomic/nonatomic的作用
其中参数主要分为三类:
读写属性: (readwrite/readonly)
setter语意:(assign/retain/copy)
原子性: (atomicity/nonatomic)
各参数意义如下:
readwrite:同时产生setter\getter方法
readonly:只产生简单的getter,没有setter。
assign:默认类型,setter方法直接赋值,而不进行retain操作
retain:setter方法对参数进行release旧值,再retain新值。
copy:setter方法进行Copy操作,与retain一样
atomic:原子性,系统默认是atomic,性能低
nonatomic:非原子性,直接从内存中取值,性能高;在iOS开发中99.99%都是写nonatomic
5.property修饰符 有拿几点需要注意的问题?
答:1.相同类型的property修饰符不能同时使用
2.不同类型的property修饰符可以多个结合在一起使用, 多个之间用,号隔开
3.iOS开发中只要写上property, 那么就立刻写上nonatomic
静态数据类型和动态数据类型
静态数据类型的特点:
在编译时就知道变量的类型,知道变量中有哪些属性和方法,在编译的时候就可以访问这些属性和方法,并且如果是通过静态数据类型定义变量, 如果访问了不属于静态数据类型的属性和方法, 那么编译器就会报错
动态数据类型的特点:
在编译的时候编译器并不知道变量的真实类型, 只有在运行的时候才知道它的真实类型,并且如果通过动态数据类型定义变量, 如果访问了不属于动态数据类型的属性和方法, 编译器不会报错
id和NSObject * 的区别?
答:NSObject *是一个静态数据类型;id 是一个动态数据类型;
动态数据类型的应用场景?
答:动态类型主要用在多态, 可以减少代码量, 避免调用子类特有的方法需要强制类型转换
动态数据类型的弊端是什么?
答:由于动态数据类型可以调用任意方法, 所以有可能调用到不属于自己的方法, 而编译时又不会报错, 所以可能导致运行时的错误
判断数据类型的有哪些方法?
答:为了避免动态数据类型引发的运行时的错误, 一般情况下如果使用动态数据类型保存一个对象, 在调用这个变量的方法之前会进行一次判断, 判断当前对象是否能够调用这个方法
构造方法
什么是构造方法?
答:在OC中init开头的方法, 我们称之为构造方法
构造方法的用途?
答:用途: 用于初始化一个对象, 让某个对象一创建出来就拥有某些属性和值
如何实现构造方法?
答:重写init方法, 在init方法中初始化成员变量
如何重写init方法?
答:重写init方法必须按照苹果规定的格式重写, 如果不按照规定会引发一些未知的错误
(1)必须先初始化父类, 再初始化子类
(2)必须判断父类是否初始化成功, 只有父类初始化成功才能继续初始化子类
(3)返回当前对象的地址
什么是自定义构造方法?为什么要自定义构造方法?
答:(1)自定义构造方法就是自定义一个init方法
(2)有时候我们需要在创建某个对象的时候,让对象的某些属性就具有值,这时候就需要传入一些参数给对象的属性,为了满足这个需求,就需要自定义构造方法
自定义构造方法的格式?
答:(1)一定是对象方法
(2)一定返回id/instancetype
(3)方法名称一定以init开头
-(instancetype)initWithAge:(int)age andName(NSString*)name;
自定义构造方法在继承中有一个原则?
答:自己的事情自己做,属于谁的属性就由谁来进行操作;
父类的属性交给父类的方法来处理,子类的方法处理子类自己独有的属性
自定义构造方法在子类,如何调用的父类构造方法的?
答:子类在重写自定构造方法时,一般使用super 调用父类的构造方法,先让父类将父类的属性进行初始化
instancetype和id区别
instancetype和id区别?
答:(1)id在编译的时候不能判断对象的真实类型;instancetype在编译的时候可以判断对象的真实类型 (2) instancetype可以返回和方法所在类相同类型的对象,id只能返回未知类型的对象;
(3)id可以用来定义变量, 可以作为返回值, 可以作为形参;instancetype只能用于作为返回值
instancetype 应用场景?
答:以后但凡自定义构造方法, 返回值尽量使用instancetype, 不要使用id
类工厂方法
什么是类工厂方法?
答:用于快速创建对象的类方法, 我们称之为类工厂方法
类工厂方法应用场景
答:类工厂方法中主要用于给对象分配存储空间和初始化这块存储空间
类工厂方法使用规范
规范:1.一定是类方法 “+”2. 方法名称以类的名称开头, 首字母小写 3.一定有返回值, 返回值是id/instancetype4.在类工厂方法实现中,调用本类的构造方法,创建实例对象,并返回实例对象
自定义类工厂方法是苹果的一个规范, 一般情况下, 我们会给一个类提供自定义构造方法和自定义类工厂方法用于创建一个对象
类工厂方法在继承中的注意点
答:以后但凡自定义类工厂方法, 在类工厂方法中创建对象一定要使用self来创建,一定不要使用类名来创建
SEL类型
SEL是什么类型?
答:SEL类型代表着方法的签名,在类对象的方法列表中存储着该签名与方法代码的对应关系
SEL有什么作用?答:(1)SEL类型的第一个作用, 配合对象/类来检查对象/类中有没有实现某一个方法(2)SEL类型的第二个作用, 配合对象/类来调用某一个SEL方法(3)配合对象将SEL类型作为方法的形参
哪个方法是用来检验对象是否实现了某个方法?
判断实例是否实现某个对象方法:(BOOL)respondsToSelector: (SEL)selector
判断类是否实现某个类方法:(BOOL)instancesRespondToSelector:(SEL)aSelector;
哪些方法是用来调用对象中SEL类型对应的方法?
答:让对象执行某个方法