NSObject的copy function如何实现的 - OurCoders (我们程序员)

OC

NSObject的copy function如何实现的

morpheus1984 发布于 2013年08月25日 | 更新于 2013年08月26日
无人欣赏。

今天看了下以前写的代码,顺便重新炒了下内存管理的旧饭,突然想知道copy这个函数具体如何实现的。还有对于NSArray NSDictionary等复杂类型对象又是如何处理的。NSString又是什么样的呢?有木有哪位大神能够给写个代码或指导个思路呢 ,@sycx @tinyfool (好吧,这么问可以能太不明确了,我直接写个代码大家看看对不对)

深复制:

- (id)CopyWithZone:(NSZone*)zone
{
 self = [[[self class]allocWithZone:zone]init];
 return self;
}

浅复制:

 - (id)CopyWithZone:(NSZone*)zone
{
 return [self retain];
}
共18条回复
tinyfool 回复于 2013年08月25日

说实话,这类东西我都觉得属于奇技淫巧,能不掺和我就懒得掺和

tinyfool 回复于 2013年08月25日

我喜欢简单省事儿的东西,能不费脑子我就不想费脑子。比如,以前玩COM我就烦引用计数,我写Java那段时间还是觉得GC很幸福。虽然GC会有一定的性能问题,但是我们也把服务器代码的性能调到非常的高。到了Objective-C,引用计数还是很烦人,虽然你知道在手机这种设备上,性能受限,引用计数不得不用。但是能省事儿我还是喜欢省事儿的。

所以我很喜欢ARC。内存管理这套东西我都玩得不是特别好。当然你需要用的时候,你就要去弄好,我当年做Epub reader的时候,性能我还是调校到了很高的程度。当时特意变态的用金庸的全集去跟iBooks比内存占用和分页速度等等。

我不反对学习的时候学深入一点,机理都弄明白,但是用的时候,我反对使用奇技淫巧的东西。很多时候,你可以选择用一些奇技淫巧的东西,也可以选择用一些架构手段去绕过去。或者是去分层,某些非常难懂,但是必要的代码放在一个层次,大量的好懂的代码放在另外一个层次。

当你的项目做到一定大的尺寸以后,你就会发现很多时候高层次的抉择,比具体代码的精妙与否更有价值。比如我们这次移植新杂志到Mac, @sycx 老师本来有点想用大量的分支去处理Mac和iOS的API不兼容性。我本质上担心的是,如果我们平台多了以后,在一个平台上加了新功能,怎么同步到别的代码上去。就觉得他那个方案多半不靠谱。

结果他做了做,发现,光是UIImageNSImage的这点小区别就够他折腾的。于是,我们改成寻找成熟的UIKit Mac版开源实现。结果移植就变得非常容易,迅速就看到了成果,而且可以预期未来两个版本几乎可以同步发行。我们甚至在新杂志的某些大的交互设计上也准备做改动,以便未来iOS和Mac版本可以开发起来更容易。

morpheus1984 回复于 2013年08月25日

启发很大,我回头想想,理下思路。。。

sycx 回复于 2013年08月25日

深复制:

- (id)copyWithZone:(NSZone*)zone
{
 id copy = [[[self class] allocWithZone:zone] init];
 copy.title = [self.title copy];
 copy.name = [self.name copy];
 return self;
}

浅复制:

- (id)copyWithZone:(NSZone*)zone
{
 id copy = [[[self class] allocWithZone:zone] init];
 copy.title = self.title;
 copy.name = self.name;
 return self;
}
nickel 回复于 2013年08月26日
  • (id)CopyWithZone:(NSZone*)zone { return [self retain]; }

这种根本就谈不上是复制,浅个屁啊,明显就是为了省事做的,如果要这样用干嘛要用复制?!既然使用的时候明确是希望copy而不是retain,必然有一定目的。而你这样硬生生地把希望用copy的地方强制为retain,很有可能在使用的时候不小心引入retain cycle之类的不明显问题的。

我个人并不同意tiny对于计数的看法,我觉得技术其实使用起来很轻松,并不会有太多麻烦。当然ARC是为了更省事没错。而且我一直认为,如果是代码逻辑引入的内存问题,ARC也救不了你。

BarryWey 回复于 2013年08月26日

如果对象的属性是『基本数据类型』,就做简单的浅克隆就够了。
如果对象的属性有『其他对象』,那么就要做深度克隆。否则可能会导致两个实例指向同一个对象

morpheus1984 回复于 2013年08月26日

@nickel NSString的copy属性其实就是起到个retain的作用 而NSMutableString则是创建了一个新的内存空间。我写的那两个copyWithZone 其实是为了表达我对浅复制和深复制的理解。NSObject的不同子类对于copyWithZone都有不同的实现

@sycx 不是很明白啊,你在浅复制里面创建了一个对象,那岂不是开辟了新的内存空间?求解释。

tinyfool 回复于 2013年08月26日

@morpheus198 你那个浅复制的代码是不是从某个单例的类的代码里面抄来的?复制当然是要创造新的内存空间啊

ibuick 回复于 2013年08月26日

这些东西去看 GNUstep 的开放源代码,相去不远,可以作为 Cooca 内部实现的重要参考。

本帖有18个回复,因为您没有注册或者登录本站,所以,只能看到本帖的10条回复。如果想看到全部回复,请注册或者登录本站。

登录 或者 注册
发布新帖
相关帖子
相关新闻
最新帖子

AltStyle によって変換されたページ (->オリジナル) /