NSObject一
objc中的类方法和实例方法有什么本质区别和联系?
类方法:
- 类方法是属于类对象的
- 类方法只能通过类对象调用
- 类方法中的self是类对象
- 类方法可以调用其他的类方法
- 类方法中不能访问成员变量
- 类方法中不定直接调用对象方法
实例方法:
- 实例方法是属于实例对象的
- 实例方法只能通过实例对象调用
- 实例方法中的self是实例对象
- 实例方法中可以访问成员变量
- 实例方法中直接调用实例方法
- 实例方法中也可以调用类方法(通过类名)
部分属性和方法:
- (BOOL)isEqual:(id)object;
就是直接比较
- (BOOL)isEqual:anObject
{
return anObject == self;
}
@property (readonly) NSUInteger hash;
- (NSUInteger)hash
{
return (NSUInteger)self;
}
isEqual 和 hash 他们都是基于对象指针的比较,若指针相同则相同。
如NSString是实现了基于值的比较,内部也重写了isEqual和hash两个方法。
另外,isEqual和hash两个方法 一定要一起重写,并且保证:两个相同的对象实例肯定具有相同的hash值,否则就是出现了不一致的情况。这时你的这个类在使用NSArray、NSDictionary,NSSet等时就有可能会出现 不是你想要的结果。比如:你只是实现了isEqual方法,在使用NSMutableArray的 removeObjectsInArray时 就会出现不能删除的情况。
superclass;
返回父类
+ superclass
{
return class_getSuperclass((Class)self);
}
- superclass
{
return class_getSuperclass(isa);
}
class;
实例方法返回的是isa指针, 类方法返回的是本身
- class
{
return (id)isa;
}
+ class
{
return self;
}
performSelector
perform是发送消息到指定的接收器并返回值
- (id)performSelector:(SEL)aSelector;
- (id)performSelector:(SEL)aSelector withObject:(id)object;
- (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;
- perform:(SEL)aSelector
{
if (aSelector)
return objc_msgSend(self, aSelector);
else
return [self error:_errBadSel, sel_getName(_cmd), aSelector];
}
- (BOOL)conformsToProtocol:(Protocol *)aProtocol;
返回是否遵循了某个协议
- (BOOL) conformsTo: (Protocol *)aProtocolObj
{
return [(id)isa conformsTo:aProtocolObj];
}
+ (BOOL) conformsTo: (Protocol *)aProtocolObj
{
Class class;
for (class = self; class; class = class_getSuperclass(class))
{
if (class_conformsToProtocol(class, aProtocolObj)) return YES;
}
return NO;
}
- (BOOL)respondsToSelector:(SEL)aSelector;
是查找有没有实现某个方法
+ (BOOL)instancesRespondToSelector:(SEL)aSelector;
判断类的对象是否响应某消息
- (BOOL)isKindOfClass:(Class)aClass;
判断是否是aClass类的实例 或者是 aClass子类的实例
- (BOOL)isKindOf:aClass
{
register Class cls;
for (cls = isa; cls; cls = class_getSuperclass(cls))
if (cls == (Class)aClass)
return YES;
return NO;
}
如果自己的isa等于aClass(aClass的父类,此处循环)就返回YES,否则返回NO
- (BOOL)isMemberOfClass:(Class)aClass;
判断是否是aClass类的实例
- (BOOL)isMemberOf:aClass
{
return isa == (Class)aClass;
}
+ (BOOL)isSubclassOfClass:(Class)aClass;
判定是否为aClass的子类
allocWithZone
平时我们在初始化一个对象的时候, [[Class alloc] init]
其实是做了两件事。 alloc 给对象分配内存空间,init是对对象的初始化,包括设置成员变量初值这些工作。
而给对象分配空间,除了alloc方法之外,还有另一个方法: allocWithZone.
在NSObject 这个类的官方文档里面,allocWithZone方法介绍说,该方法的参数是被忽略的,正确的做法是传nil或者NULL参数给它。而这个方法之所以存在,是历史遗留原因。
Do not override allocWithZone: to include any initialization code. Instead, class-specific versions of init… methods.
This method exists for historical reasons; memory zones are no longer used by Objective-C.
而使用alloc方法初始化一个类的实例的时候,默认是调用了 allocWithZone 的方法。在使用单例模式时 ,覆盖allocWithZone方法的原因 :为了保持单例类实例的唯一性,需要覆盖所有会生成新的实例的方法,如果有人初始化这个单例类的时候不走[[Class alloc] init] ,而是直接 allocWithZone, 那么这个单例就不再是单例了。
copy
浅拷贝
mutableCopy
深拷贝