iOS复习笔记15:NSObject



为了描述方便,把如下代码贴出来:
@interface Student:NSObject
-(void)go;
-(void)showName:(NSString *)name;
-(void)introduce:(NSString *)name :(NSString*)address;
@end


Student* stu = [[Student alloc]init];


一 创建和初始化方法
alloc
allocWithZone
new
copy -- 只有不可变到不可变是浅拷贝(相当于retain),其他都是深拷贝,产生不可变的副本(NSString, NSSet等)
mutableCopy -- 深拷贝,产生可变的副本(NSMutablString, NSMutablSet等)
init


重点看copy和mutableCopy
copy:只有不可变到不可变是浅拷贝(相当于retain),其他都是深拷贝,产生不可变的副本(NSString, NSSet等)
mutableCopy:深拷贝,产生可变的副本(NSMutablString, NSMutablSet等)
并不是所有的对象都支持copy,mutableCopy;
遵守NSCopying/NSMutableCopying协议的类可以发送copy/mutableCopy消息。
这两个协议里面分别声明了下面两个方法:
- (id)copyWithZone:(NSZone *)zone;
- (id)mutableCopyWithZone:(NSZone *)zone;

示例:
<pre name="code" class="objc">@interface Student:NSObject <NSCopying>
@end

@interface Student
(id)copyWithZone:(NSZone *)zone
{
	// 创建的副本对象不需要释放,有调用者释放
	// [self class]防止继承之后,返回父类对象
	Student* copy = [[[self class] allocWithZone:zone] init];


	return copy;
}
@end



二 内存管理方法retain 增加对象的计数器retainCount 返回一个对象当前的计数器release 减少对象的计数器autorelease 自动减少对象的计数器,但是以推迟的方式来实现。dealloc 应用于类来释放对象实例变量并释放动态内存三 判断方法isKindOfClass:判断对象是否是某个类或子类的对象isMemberOfClass:判断对象是否是某个类的对象comfirmsToProtocal:判断对象是否实现了某个协议instancesRespondToSelector:判断对象是否实现了某个方法respondsToSelector:判断类是否实现了某个方法四
 间接调用performSelector:performSelector:withObjct:performSelector:withObjct:withObjct:performSelector:withObjct:afterDelay:
// 相当于[stu go];
[stu performSelector:@selector(go)];
// 相当于[stu showName:@"Jun"];
[stu performSelector:@selector(showName:) withObjct:@"Jun"];
相当于[stu introduce:@"Jun":@"address"];
[stu performSelector:@selector(introduce::) withObjct:@"Jun" withObjct:@"address"];
// 延时2秒之后调用
[stu performSelector:@selector(showName:) withObjct:@"Jun" afterDelay:2];



五 描述
NSObject有一个description方法
+ (NSString *)description;
当我们调用NSLog(@"%@", instance);时,就会调用description方法。
自定义类时,可以重写这个方法。


六 反射
根据字符串反射成类和方法


1 Class反射
// 字符串类名到类
NSString* className = @"Student";
Class class = NSClassFromString(className);
Person* p = [[class alloc] init];
// 类到字符串类名
NSString* strClass = NSStringFromClass([Person class]);




2 方法反射
// 字符串方法名到方法
NSString* funName = @"go";
SEL selector = NSSelectorFromString(funName);
[stu performSelector:selector];
// 方法到字符串方法名
NSString* strFun = NSStringFromSelector(selector);




七 NSObject本质
@interface NSObject <NSObject> {
        Class isa;
}


可以看到NSObject对象只有一个成员变量Class isa;
Class又是什么呢?
typedef struct objc_class *Class;


它结构体objc_class指针的别名。


objc_class的定义如下:
struct objc_class {
    Class isa;
};



跟NSObject定义类似,此外还有id也是这样的。
typedef struct objc_object {
    Class isa;
} *id;
所以id就是结构体objc_object指针。


从上面可以看出,NSObject,objc_class,objc_object都仅有一个objc_class * 类型,也就是Class类型的变量isa
以得出结论,类是用objc_class结构体表示的,对象是用objc_object结构体表示的,对象的isa用来标示这个对象是哪个类的实例。
看下面的源代码:


- (BOOL)isMemberOfClass:(Class)cls {
    return [self class] == cls;
}


- (Class)class {
    return object_getClass(self);
}


Class object_getClass(id obj)
{
    return _object_getClass(obj);
}


static inline Class _object_getClass(id obj)
{
    if (obj) return obj->isa;
    else return Nil;
}



如果obj不空,返回的Class类型就是obj->isa,否则,返回的是Nil。
这就从源码上证实了isa就是代表一个对象的类型。

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。