1 copy vs mutableCopy
现在需要说明一下:
网上关于这两个方法的说明都比较详细,这里总结一下:
1. 如果对一不可变对象复制,copy是指针复制(浅拷贝)和mutableCopy就是对象复制(深拷贝)。
2. 如果是对可变对象复制,都是深拷贝,但是copy返回的对象是不可变的。
3. NSCopyobject()他实际上是浅拷贝,所以需要你需要自己处理需要深拷贝的成员变量(指针变量),还有一点NSCopyObject是对象内存的指针拷贝,因此原对象的retaincount也被复制过来。
4. 对于容器类对象,容器存储的指针都是浅拷贝,所以如果需要深拷贝容器内指针所指向的对象,你需要遍历容器中的指针,分别进行深拷贝。
5.其实copy/mutableCopy,类似于设计模式的clone模式,当你进行深clone或者浅clone,你需要做的就是重载copyWithZone或者mutableCopyWithZone。
2 NSAutoreleasePool
在每一个线程中都有一个存放自动释放池堆栈。当您创建一个新的自动释放池时,它被添加到堆栈的顶部。当自动释放池被回收时,它们从堆栈中被删除。当一个对象收到送autorelease
消息时,它被添加到当前线程的目前处于栈顶的自动释放池中。如果您释放了一个不是位于堆栈顶部的自动释放池,则这会导致堆栈中所有位于它上面的(未释放的)自动释放池,连同它们包含的所有对象一起被释放。这样就可能会造成程序奔溃。
一般自动释放池用于下面这种情况:
1. 不是基于Application Kit的程序,比如命令行工具,则没有对自动释放池的内置支持;您必须自己创建它们。
2. 如果你创建了一个新的线程,你必须创建自己的自动释放池,避免内存泄漏。不过如果线程不会发起Cocoa调用,那么也可以不创建自动释放池(不过这种情况基本没遇到过)。
3. 在一些会产生大量临时对象的地方,可以在循环内部创建一个自动释放池,以便在下次迭代之前销毁这些对象。这可以帮助减少应用程序的最大内存占用量。
NSAutoreleasePool与drain , retain , release的关系(在基于引用计数的环境下(一般我们开发的环境都是这个))。
一般NSAutoreleasePool时,我们都只会利用drain,其原理是drain会给自动释放池发送dealloc消息,从而导致自动释放池给它内部所有的对象发生release消息,来清空释放池,和回收对象的内存。
但是如果你给一个NSAutoreleasePool发生retain消息,就会出现异常,如果给NSAutoreleasePool发送release消息,默认是不做任何事情。
3.retain ,release ,autorelease(保证上下文中存在自动释放池)
首先给出下面说明:
-
当您创建一个对象时,该对象的保留计数为1。
-
当您向一个对象发送
retain
消息时,该对象的保留计数加1。 -
当您向一个对象发送
release
消息时,该对象的保留计数减1。当您向一个对象发送
autorelease
消息时,该对象的保留计数会在将来的某个阶段减1
这里需要注意一下是:在将集合类的元素移除集合是,会元素发送release消息。加入时会发生retain消息。其实去看看cocoa2D的容器代码就会发现这个。
同时还需要注意循环引用的问题,一般的解决方法将强引用改为弱引用。