1.#import有两个用途,第一个用途:与C 语言中的 include 完全一样。第二个用途:可以自动防止文件内容被重复拷贝,也就是说多次书写#import <Foundation/NSObjCRuntim.h>就只拷贝一次,相当于只写了一次。
2.类方法的好处和使用场合
(1) 不依赖于对象,执行效率高(2) 能用类方法,尽量用类方法(3) 场合:当方法内部不需要使用到成员变量时,就可以改为类方法
可以允许类方法和对象方法同名3.self的用途:(1) 谁调用了当前方法,self就代表谁* self出现在对象方法中,self就代表对象* self出现在类方法中,self就代表类
(2) 在对象方法利用"self->成员变量名"访问当前对象内部的成员变量
(3)[self方法名]可以调用其他对象方法/类方法
使用 self 与 super调用方法的区别:使用 self 调用方法时,self先从当前类中寻找方法,如果没有寻找到再去父类中寻找。而super直接在父类中寻找方法。
4.super的作用1.直接调用父类中的某个方法2.super处在对象方法中,那么就会调用父类的对象方法
super 处在类方法中,那么就会调用父类的类方法
3.使用场合:子类重写父类的方法时想保留父类的一些行为
5.多态
多态就是用父类类型的指针创建子类的对象,比如Dog类继承了Animal类,下面都是多态:
Animal *aa = [Dog new];
Dog *dd = (Dog *)aa;
1.没有继承就没有多态2.代码的体现:父类类型的指针指向子类对象3.好处:如果函数/方法参数中使用的是父类类型,可以传入父类、子类对象4.局限性:父类类型的变量不能直接调用子类特有的方法。必须强转为子类类型变量后,才能直接调用子类特有的方法
6.
在 xcode4.4 之后,@PRoperty的功能更加强大,它同时具有了@synthesize的功能,比如@property int age;具有如下三个功能:(1)生成_age成员变量的get和 set 方法的声明(2)生成_age成员变量的get和 set 方法的实现
(3) 生成一个名为_age的成员变量
7.
@property的参数:
(1) set方法内存管理相关的参数
(a) retain:release旧值,retain新值(适用于OC 对象类型)(b) assign:直接赋值(默认,适用于非OC 对象类型),常用在 BOOL、int等基本数据类型。(c) copy:release旧值,copy新值,常用在NSString对象
(2) 是否要生成set方法(a) readwriter:同时生成set和 get 方法的声明和实现(b) readonly:只生成get的声明和实现
(3) 多线程管理(a) nonatomic:性能高(一般都是使用这个)(b) atomic:性能低(默认)
(4) set和 get 方法的名称(a) setter:决定了set方法的名称,一定要加个冒号“:“(b) getter:决定了get方法的名称,不要加冒号
(5) strong和 weak(a) strong:用于一般对象
(b) weak:用于UI 控件
8.默认情况下,除字符串对象外,使用NSLog和%@打印对象的结果都是<类名 对象所在内存地址>。使用NSLog和%@打印对象的步骤如下:1.调用对象p的-description方法2.拿到-description方法的返回值(NSString *)显示到屏幕上3.-description方法默认返回的是“类名+内存地址
在必要情况下,我们需要重写description方法以达到改变输出结果目的,
还有一个以“+”开头的description,“+”开头的description决定的是类对象的输出结果,“-”开头的description决定的是实例对象的输出结果。
当然也可以像重写“-”开头的description一样去重写它。【备注】类也是对象,任何类都是 Class的对象,获得类对象(和类的对象不是同一个概念)的方法为
Class c = [Person class];
9、SELSEL其实是对方法的一种包装,将方法包装成一个SEL类型的数据,去找对应的方法地址。找到方法地址就可
以调用方法, 其实消息就是SEL。对于下列方法调用:
[p test2];
主要有以下步骤:1.把test2包装成SEL类型的数据2.根据SEL数据找到对应的方法地址3.根据方法地址调用对应的方法比如一个类中有两个方法:+test和-test2每个方法在内存中的地址都有一个对应的SEL与之对应
SEL s1 == +test地址
SEL s2 == -test2地址
对象找要调用的方法时,isa指针会根据调用的方法名在类中找到相关的SEL对象(方法地址)去调用。所以,调用方法还可以用如下形式:
[p performSelector:@selector(test2)];
performSelector:@selector(test2)返回的就是test2的方法地址。如果方法还有参数,比如- (void)test3:(NSString *)abc,还可以按照如下格式调用:
[p performSelector:@selector(test3:) [Object:@”abc”]];
对于上述调用方法,test3后一定要加”:“,因为”:”也是有参数方法的方法名的一部分。
10、内存管理(高频面试题)
无论是 ios 还是 android 中,系统对每个程序运行时内存的占用都有一个限制,默认都是几十M 左右大小,当程序占用的内存的大小超过限制时,程序可能就会被强制退出。拿 iphone4来说,当程序内存占用超过40M时,会出现内存警告,当内存占用达到45M,还会再一次内存警告,对于以上两次警告如果不做出释放内存操作,当达到120M时,系统会自动kill掉程序。在内存中,分为堆和栈,栈中主要存放变量,堆中主要存放对象。栈中的东西是系统自动回收的,当一个变量使用完毕后,存放在栈中的东西会立刻被回收。但堆中存储的东西是不会随便回收的。
每个 OC 对象里都有一个引用计数器,是一个整数,用来统计正在被引用多少次,每个引用计数器占用4个字节,对象刚刚创建时引用计数器默认为1。如果OC 对象引用计数器为 0 时,系统就可以回收这个对象了。引用计数器的操作:
(1) 给对象发送一条 retain 消息,可以使引用计数器值+1(retain方法返回对象本身)(2)给对象发送一条release消息,可以使引用计数器值-1(3) 给对象发送一条retainCount消息,可以获得当前的引用计数器值
对象的销毁:
(1) 当一个对象的引用计数器的值为0 时,那么它将被销毁,其占用的内存会被系统回收。(2)当一个对象被销毁时,系统会自动向对象发送一条dealloc消息
(3) 一般会重写 dealloc 方法,在这里释放相关资源,dealloc就像对象的遗言。(4)一旦重写了dealloc方法,就必须调用[super dealloc],并且放在最后面调用。(5)不要直接调用dealloc方法。(6)一旦对象被回收了,它占用的内存不再可用,坚持使用就会导致程序崩溃(指针错误)。概念:僵尸对象:所占用的内存已经被回收的对象,僵尸对象不能再使用野指针:指向僵尸对象的指针,给野指针发送消息会报错空指针:没有指向任何东西的指针(存储的东西是 nil、null、0),给空指针发送消息不会报错。【备注】nil与 null 不同,null是一个宏定义,值为0,nil表示无值,任何变量在没有赋值之前都是nil,对于真假判断,只有nil和 false 表示假,其他均为真。内存管理原则:(1)谁创建,谁release:如果你通过 alloc、new或[mutable]copy来创建一个对象,那么必须调用release或 autorelease(2)谁retain,谁release:只要你调用了 retain,无论这个对象如何生成的,你都要调用release。综上:有始有终,有加就有减。曾经让对象计数器+1,就必须在最后让对象计数器-1。
新闻热点
疑难解答