不足之处,欢迎指正交流。。。
当用 = 将一个变量的值赋值给另外一个变量的时候就会出现一般意义上的copy操作,或者说是一般赋值操作。
myInt2 = myInt1
这句表达式,是指将
myInt1
所在内存空间中的Integer值赋值给myInt2所在内存空间中。因为copy函数的原因,内存空间中两块独立的内存中存储着同一个值。
但是如果对Core Foundation对象运用这一方法,有可能并没有对自己本身进行一个拷贝和复制,而只是对该对象进行了引用。
例如,刚接触到Core Foundation的人有可能会想着通过
myCFString2 = myCFString1
这一表达式来对CFString对象进行复制操作。
但是这一操作实际上并没有对这个string数据进行复制。因为这二者都有CFStringRef类型,这个表达式只能对对象产生一个引用。因为使用了copy操作,创建了两个对CFString对象的引用。这种复制操作是很快的,因为只是复制了对对象的引用,但是如果对一个可变对象使用这种操作的话是很危险的。对于在一个程序中所使用的全局变量,如果在这个程序的其中一个部分里是通过这个变量的引用来改变这个对象,那么在这个程序里的其他部分使用这个对象引用的,就没有机会知道原来的值的改变。
如果想要对一个对象进行复制,就需要使用Core Foundation所提供的方法。我们继续以CFString为例,应该使用CFStringCreateCopy来创建一个与最原始的变量相同的对象。Core Foundation不仅有CreateCopy还有CreateMutableCopy方法来返回一个可以修改的可变类型的变量。
浅复制
复制那些可以容纳包含其他对象的集合对象的时候,必须小心谨慎。当用= 来对那些对象进行复制操作的时候,仅仅是对那个对象的引用进行了复制。对比基本数据类型中的CFString和CFData,CreateCopy对CFArray和CFSet这种集合类对象提供了浅拷贝的方法。对于这些数据类型来说,浅拷贝就意味着会创建一个新的集合类对象,但是原始对象中所包含的内容并没有被复制出来 —— 仅仅是对这个对象的引用进行了复制。这种复制是有用的如果你有一个不可变数组,并且你像对这个数组进行重新布置的时候。在这种情况下,你没有必要复制这个数组中所包含的对象,因为你将会对他们进行改变 ,就没有必要利用这份内存,你只是想要这个包含对象的集合进行改变。当对基本数据类型进行复制的时候同样会存在一样的问题。
—— 浅拷贝是对内存地址的拷贝,是让目标对象指针和源对象指向同一块内存区域。浅拷贝是对对象的简单拷贝,让几个对象公用同一块内存,当这块内存销毁的时候,指向这块内存的几个指针需要重新定义才能继续使用,否则会成为野指针。在iOS里,retain会对对象进行技术,当对象release的时候由于计数器的存在,并不会轻易的销毁内存。
深拷贝
深拷贝是指拷贝对象的具体内容,而内存地址是自主分配的,拷贝结束之后,两个对象虽然存的值是相同的,但是内存地址不一样,两个对象也互不影响,互不干涉。
copy 与 retain 的区别:
copy 是创建一个新对象,retain 是创建一个指针,引用对象计数加一。 copy属性标识两个对象内容相同,新的对象retain count为1, 与旧有对象引用计数无关,旧有对象没有变化。copy减少对象对上下文的依赖。