做个学习笔记,初学object-c。
-、SEL类型。
object-c在编译的时候,会根据方法的名字(包括参数序列),生成一个用于区分方法的id,这个id的类型就是SEL。只要是方法名字(包括参数序列)一样,则两个方法的id
就一样。在超类子类,或不相干的类之间也是这样的。
二、IMP
typedef id (*IMP)(id, SEL, );
定义函数指针。 与c中的void(*名字) (id, SEL, NSString*);是一样的。
三、Class
当在编译成功的时候,类里面会有一个变量用于保存这个类的信息。typedef struct objc_class *Class;
Class 被定义为一个指向 objc_class的结构体指针,这个结构体表示每一个类的类结构。而 objc_class 在objc/objc_class.h中定义如下:
struct objc_class {
struct objc_class super_class; /*父类*/
const char *name; /*类名字*/
long version; /*版本信息*/
long info; /*类信息*/
long instance_size; /*实例大小*/
struct objc_ivar_list *ivars; /*实例参数链表*/
struct objc_method_list **methodLists; /*方法链表*/
struct objc_cache *cache; /*方法缓存*/
struct objc_protocol_list *protocols; /*协议链表*/
};
四、id
typedef struct objc_object {
Class isa;
} *id;
id 变量名 = [类名 new];
实际上就是在运行时为我们初始化好了Class的指针,并把这个指针返回给我们,我们初始化之后得到的对象就是一个指向这个对象的Class指针。
IMP 是运行时 结合id和SEL 找到的
__inline__ IMP
objc_msg_lookup(id receiver, SEL op)
{
if(receiver)
return sarray_get(receiver->class_pointer->dtable, (sidx)op);
else
return nil_method;
}
五、类方法
1、类方法可以调用类方法
2、类方法不能调用实力方法,但是类方法可以通过创建对象来访问实例方法。
3、类方法不可以使用实例变量,但可以使用self,因为self不是实例变量
4、可以通过类或对象调用类方法
o-c中的self跟c++中的不一样,o-c中实例方法中的self是对象的首地址,而类方法里的是Class
六、copy 和 retain 的区别
copy和retain的区别在于它们的字面意思,不同之处在于一个是直接引用(比如说对象的引用),然后retain count+1,另外一个是复制使用(比如说字符串的使用),将复制到的对象a1的retain count+1.
七、浅复制只是复制对象本身,对面里面的属性、包含的对象不会被复制。深复制不仅复制对象本身还复制里面的属性。Foundation支持复制的类,默认识浅复制。
自定义对象要想拥有复制特性,要实现NSCopying 或 NSMuTableCopying 协议。实现该协议中的copywithzone 或 mutablezcopywithone 方法。
深浅复制就是对函数的不同实现。
u比如person 类
-(id)copywithzone:(nszone *)zone
{
//浅拷贝
person *per = [[[self class] allocwithzone:zone]init];
person.age = _age;
person.name = _name;
return person;
//深拷贝
person *per = [[[self class] allocwithzone:zone]init];
nsmutablestring name =[_name mutablecopy];
person.name = name;
[name release];
return person;
}
注意:foundation 可复制对象,当我们copy的是一个不可变的对象时,它的作用相当于retain(cocoa做的内存优化)
当我们使用mutablecopy时,无论源对象是否可变,副本是可变的,并且实现了真正意义上的拷贝。
当我们copy 的是一个可变对象是,副本对象是不可变的,同样实现了真正意义上的拷贝。