关于isa,copy以及mutableCopy的一个比较综合的问题

来源:5-3 类对象与元类对象&消息传递相关面试问题

彼岸散人

2018-11-25

老师您好,整个课程基本上已经听完了,最近还在查漏补缺。

在听完了isa和 superClass的课程后,就一时兴起的想到了类对象调用- (void)copy;和- (void)mutableCopy;

但调用的结果却出现了一些意料之外的问题。代码如下:

int main(int argc, const char * argv[]) {
    @autoreleasepool {
    Class zrCarClass = [ZRCar class];
    id unknownClass1 = [ZRCar mutableCopy];
    id unknownClass2 = [ZRCar copy];
    
    NSLog(@"%@ --- %@ --- %@", zrCarClass,
							   unknownClass1, 
							   unknownClass2);
    NSLog(@"%p --- %p --- %p", zrCarClass, 
							   unknownClass1, 
							   unknownClass2);
	}
    return 0;
}

首先,如果是ZRCar的实例对象调用copy或者mutableCopy的话,如果该实例对象没有实现对应的协议方法的话,会直接崩溃。

其次,根据superClass的特性来看,meta-class最终是指向root-meta-class,命中不了对应的类方法后,会根据superClass指向root-class来查找对应的实例方法。所以说类方法能调用copy以及mutableCopy这个是没问题的。

但问题在于,为什么类对象调用这两个方法的话,不会崩溃呢?

此外,为什么mutableCopy在被调用后,并没有产生相应的新内存开辟呢?这个是不是和类对象本身是静态对象有关?

还望老师能够给出详细的解答,并给一些具体的求证方法。Thx。

写回答

2回答

慕尼黑5054925

2020-01-05

通过类调用copy和mutableCopy不会崩溃,并且返回的始终是一个单例类对象,原因是NSObjec还定义了copy和mutableCopy的类方法,通过查看源码知道返回的始终是self(当前类对象),

+ (id)copyWithZone:(struct _NSZone *)zone {

    return (id)self;

}

+ (id)mutableCopyWithZone:(struct _NSZone *)zone {

    return (id)self;

}

而NSObjec类对象的isa指针是指向根元类的,所以这两个方法会存储在根元类方法列表。

1
0

于海

2018-11-25

类对象在内存中只有一个 多次调用copy mutablecopy始终都是返回系统创建的同一个类对象结果 自定义的普通对象没有copy方法实现 调用copy当然会崩溃啦 能调用编译不报错是因为nsobject声明遵从了copy协议

0
1
xiaozhi6156
普通对象也是继承于NSObject,它不也会在方法查找的时候,最终找到RootClass么?
2018-11-27
共1条回复

资深大牛带你深度剖析ios高级面试

从BAT/TMD名企真题入手,结合源码及应用,构建完整iOS知识体系

1749 学习 · 600 问题

查看课程