构造方法
是一个对象在初始化的时候执行的方法
init才是真正的构造方法
new方法执行2个方法
+alloc:去给对象分配一个内存空间;
-init;初始化这个对象;
如果super init没有执行成功或正确执行,则无法返回一个正确的对象,那么此时会返回0(nil);
如果super init执行成功了,会返回一个指针,那个值赋值给self,则self是一个非0数
对象全部在堆区,指针都是在栈区
执行自定义赋值操作
构造方法的操作有两种:
1,重写。
优点:实现简单。不足:不能够根据不同对象赋不同的值,属性的值是固定的
2,自定义构造
优点:使用灵活,可以根据不同的对象给属性设定不同的值,不足:写法比较麻烦一些
要注意 用@property生成的属性是private,子类要使用就要在父类属性自己写上属性
3 ,子类继承父类自定义构造的写法
在自定义构造时,要调用父类的自定义构造,而不是NSObject的init。这样才能隔离父类的变化。而且,父类的属性可以保持私有化private
堆区内存空间需要手动回收
栈区内存空间需要自动回收
oc只有重写,没有重载
static修饰全局变量,只能在本文件内访问,如果修饰的是局部变量,只能在第一个使用的时候才会创建,后面再使用都是复用
构造方法必须以init开头,且第二个单词开始首字母大写
id指针动态调用方法时,点语法不适用,必须强转
1,类与对象
2,定义类中的方法与属性
3,定义有参数的方法
4,封装属性 set与get方法
5,self调用方法或属性
6,super调用父类方法
7,继承
8 ,多态
9,id指针
10,组合->把一个对象当做另一个类的属性
11 ,@property->功能1 生成属性 2生成get与set声明,实现set与get方法
12,属性的作用域
13,点语法
14,构造方法
15,NSString
Category
:把一个类分作多个部分
作用:
不该变原有的类,去给原来有的类添加功能(方法)
写法:
命名:原有的类名+分类名
声明:
@interface Person(分类名)
// 你要添加的功能......
@end
实现
@implementation Person(分类名)
// 实现你要添加的功能...
@end
好处:
1,可以把一个类分模块,便于协同开发,并优化类的结构
2,不该变类名,给类添加功能
注意的问题
1 分类不能写(添加)属性,只能写(添加)方法
2 分类中的方法不能与主类和其他分类重复,会覆盖其他类的方法
3 分类中可以直接用主类的属性,但是属性的权限要>=@protected
4. 不同分类中重写了同一个方法,那么哪个分类最后编译,则哪个分类的方法执行
5,主类永远在分类之前编译
编译顺序:父类->主类->分类(多个分类是可以调整顺序的)
分类的另一个用法:去给oc提供的类进行分类,添加额外的功能,如:NSString
一 基本原理
Objective-C的内存管理机制与.Net/Java那种全自动的垃圾回收机制是不同的,它本质上还是C语言中的手动管理方式,只不过稍微加了一些自动方法。
1 Objective-C的对象生成于堆之上,生成之后,需要一个指针来指向它。
ClassA *obj1 = [[ClassA alloc] init];
2 Objective-C的对象在使用完成之后不会自动销毁,需要执行dealloc来释放空间(销毁),否则内存泄露。
[obj1 dealloc];
这带来了一个问题。下面代码中obj2是否需要调用dealloc?
ClassA *obj1 = [[ClassA alloc] init];
ClassA *obj2 = obj1;
[obj1 hello]; //输出hello
[obj1 dealloc];
[obj2 hello]; //能够执行这一行和下一行吗?
[obj2 dealloc];
不能,因为obj1和obj2只是指针,它们指向同一个对象,[obj1 dealloc]已经销毁这个对象了,不能再调用[obj2 hello]和[obj2 dealloc]。obj2实际上是个无效指针。
如何避免无效指针?请看下一条。
3 Objective-C采用了引用计数(ref count或者retain count)。对象的内部保存一个数字,表示被引用的次数。例如,某个对象被两个指针所指向(引用)那么它的retain count为2。需要销毁对象的时候,不直接调用dealloc,而是调用release。release会让retain count减1,只有retain count等于0,系统才会调用dealloc真正销毁这个对象。
ClassA *obj1 = [[ClassA alloc] init]; //对象生成时,retain count = 1
[obj1 release]; //release使retain count减1,retain count = 0,dealloc自动被调用,对象被销毁
我们回头看看刚刚那个无效指针的问题,把dealloc改成release解决了吗?
ClassA *obj1 = [[ClassA alloc] init]; //retain count = 1
ClassA *obj2 = obj1; //retain count = 1
[obj1 hello]; //输出hello
[obj1 release]; //retain count = 0,对象被销毁
[obj2 hello];
[obj2 release];
[obj1 release]之后,obj2依然是个无效指针。
|