NSObject一

NSObject一


objc中的类方法和实例方法有什么本质区别和联系?

类方法:

  1. 类方法是属于类对象的
  2. 类方法只能通过类对象调用
  3. 类方法中的self是类对象
  4. 类方法可以调用其他的类方法
  5. 类方法中不能访问成员变量
  6. 类方法中不定直接调用对象方法

实例方法:

  1. 实例方法是属于实例对象的
  2. 实例方法只能通过实例对象调用
  3. 实例方法中的self是实例对象
  4. 实例方法中可以访问成员变量
  5. 实例方法中直接调用实例方法
  6. 实例方法中也可以调用类方法(通过类名)

部分属性和方法:

- (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

深拷贝

posted @ 2016-03-09 15:15  孙焱焱  阅读(191)  评论(0编辑  收藏  举报