美文网首页
2018-12-10 深拷贝浅拷贝

2018-12-10 深拷贝浅拷贝

作者: 惊蛰_e3ce | 来源:发表于2019-11-20 10:23 被阅读0次

1:用copy修饰的 或者[XXX copy]的 变量肯定是不可变的。即便是修饰NSMutableArray或者NSMutableDictionary 所以通常用Strong来修饰NSMutableArray NSMutableDictionary 否则适用可能会闪退

2:用copy修饰或者[xxx copy],要看源对象是否是可变的,来决定只拷贝指针,还是也拷贝对象到另一块内存空间 即如果是NSArray、NSDictionary拷贝指针 NSMutableArray NSMutableDictionary拷贝生成新对象

3:对象之间mutableCopy赋值,肯定会拷贝整个对象内存到另一块内存中
如果NSArray中有Person对象 mutableCopy只会对NSArray进行深拷贝 Array内部的Person、ViewController、NSMutableString等对象一律不变(可以节省内存空间?)即新Array的地址空间变了 但是里面的对象还是老对象
苹果官方称为:one-level-deep copy 集合的单层深拷贝

4:[[NSDictionary alloc] initWithDictionary:someDictionary copyItems:YES]
如果你用这种方法深拷贝,集合里的每个对象都会收到 copyWithZone: 消息。如果集合里的对象都遵循 NSCopying 协议,那么对象就会被深拷贝到新的集合。如果对象没有遵循 NSCopying 协议,而尝试用这种方法进行深拷贝,会在运行时出错。
5:[NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:oldArray]] 集合的归档解档可以完全生成新对象 归档解档貌似一样要序列化 😄
部分内容来自:https://www.jianshu.com/p/eb1b732b737d

runtime对应源码:
void objc_setProperty_nonatomic_copy(id self, SEL _cmd, id newValue, ptrdiff_t offset)
{
reallySetProperty(self, _cmd, newValue, offset, false, true, false);
}

static inline void reallySetProperty(id self, SEL _cmd, id newValue, ptrdiff_t offset, bool atomic, bool copy, bool mutableCopy)
{
if (offset == 0) {
object_setClass(self, newValue);
return;
}

id oldValue;
id *slot = (id*) ((char*)self + offset);

if (copy) {

/*
The returned object is implicitly retained by the sender, who is responsible for releasing it. The copy returned is immutable if the consideration “immutable vs. mutable” applies to the receiving object; otherwise the exact nature of the copy is determined by the class.
返回的对象由负责释放它的发送者隐式保留(隐式retain)。 如果将不可变用于接收,则返回的副本是不可变的。 否则,副本的确切性质由类别决定。
1:没实现copyWithZone相关的copy协议会崩溃
2:会隐式retain 修饰不可变时和retain或者strong区别不大
/
newValue = [newValue copyWithZone:nil];
} else if (mutableCopy) {
newValue = [newValue mutableCopyWithZone:nil];
} else {
if (
slot == newValue) return;
newValue = objc_retain(newValue);
}

if (!atomic) {
    oldValue = *slot;
    *slot = newValue;
} else {

//atomic线程安全的自旋锁
spinlock_t& slotlock = PropertyLocks[slot];
slotlock.lock();
oldValue = *slot;
*slot = newValue;
slotlock.unlock();
}

objc_release(oldValue);

}

自定义类的copy

  • (id)copyWithZone:(NSZone *)zone {
    Person *p = [[self class] allocWithZone:zone];
    p.name = self.name;
    return p;
    }
  • (id)mutableCopyWithZone:(NSZone *)zone {
    Person *p = [[self class] allocWithZone:zone];
    p.name = self.name;
    return p;

}
allocWithZone方法介绍说,该方法的参数是被忽略的,正确的做法是传nil或者NULL参数给它。而这个方法之所以存在,是历史遗留原因;所以这个zone一直是nil 系统会分配新的内存空间 所以自定义类全是深拷贝?

  • (instancetype)sharePseron {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
    _p = [[self alloc] init];;
    });
    return _p;
    }
  • (instancetype)allocWithZone:(NSZone *)zone {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
    _p = [super allocWithZone:zone];
    });
    return _p;
    }
  • (id)copyWithZone:(NSZone *)zone
    {
    return _p;
    }

相关文章

  • iOS深拷贝(MutableCopy)与浅拷贝(Copy)的区别

    深拷贝和浅拷贝的概念 iOS中有深拷贝和浅拷贝的概念,那么何为深拷贝何为浅拷贝呢?浅拷贝:浅拷贝并不拷贝对象本身,...

  • iOS - copy 与 mutableCopy

    一说到拷贝,就不得不提浅拷贝和深拷贝。 何谓浅拷贝?何谓深拷贝? 往简单的说: 浅拷贝:拷贝地址。 深拷贝:拷贝内...

  • iOS面试题-第二页

    11.深拷贝和浅拷贝的理解. 深拷贝;拷贝的内容. 浅拷贝:拷贝的指针. 深拷贝如: NSMutableDicti...

  • js浅拷贝深拷贝

    js浅拷贝,深拷贝的简单实现 基础数据 浅拷贝 深拷贝

  • JS中的深拷贝与浅拷贝

    知乎:js中的深拷贝和浅拷贝? 掘金: js 深拷贝 vs 浅拷贝 前言 首先深拷贝与浅拷贝只针对 Object,...

  • iOS--拷贝相关题

    1、什么是深拷贝什么是浅拷贝?浅拷贝和深拷贝的区别 * 浅拷贝(shallow copy):指针拷贝,对于被拷贝对...

  • 2018-10-10day9函数基础

    1.浅拷贝、深拷贝 copy.copy(对象):浅拷贝copy.deepcopy(对象):深拷贝""" """拷贝...

  • 2018-10-10函数基础

    深拷贝和浅拷贝 深拷贝 copy.deepcopy(对象)浅拷贝 copy.copy(对象)深拷贝: 将对象对应的...

  • 深拷贝和浅拷贝

    1.深拷贝:地址的拷贝 2.浅拷贝:是值得拷贝 深拷贝和浅拷贝的区别 A拷贝B B变A变是浅拷贝 A拷贝B B变A...

  • 对象深拷贝和浅拷贝

    浅拷贝 深拷贝 深拷贝的递归方法 深拷贝的JSON方法

网友评论

      本文标题:2018-12-10 深拷贝浅拷贝

      本文链接:https://www.haomeiwen.com/subject/jqhdhqtx.html