Objective c 通过覆盖Obj-C中的版本重用NSObject

Objective c 通过覆盖Obj-C中的版本重用NSObject,objective-c,overriding,release,reusability,nsobject,Objective C,Overriding,Release,Reusability,Nsobject,我正在使用单例类实现一个对象重用方案 我主要做的是: MyClass* obj = [[MyClassBank sharedBank] getReusableItem]; 银行只是一个NSMutableSet,经过调整以获得最佳的可重用性。当我很高兴地实现这个单例时,我想,当我完成“obj”时,我将只执行以下操作: 目前,如果我想以这种方式使用我的代码,我的代码可以工作,但我后来意识到,有时我会将“obj”添加到“NSCollection”中,有时我会调用: [theCollection re

我正在使用单例类实现一个对象重用方案

我主要做的是:

MyClass* obj = [[MyClassBank sharedBank] getReusableItem];
银行只是一个NSMutableSet,经过调整以获得最佳的可重用性。当我很高兴地实现这个单例时,我想,当我完成“obj”时,我将只执行以下操作:

目前,如果我想以这种方式使用我的代码,我的代码可以工作,但我后来意识到,有时我会将“obj”添加到“NSCollection”中,有时我会调用:

[theCollection removeAllObjects];
首先,我考虑创建自己的由集合组成的类,然后迭代集合中的对象并调用:

[[MyClassBank sharedBank] doneWithItem:obj];
但是,这太麻烦了,不是吗

一个巧妙的想法(我想)突然出现在我的脑海中,那就是覆盖:
-(单向无效)释放,因此,我立即跳转到苹果的文档中,但遇到以下问题:

您只需要实现此方法来定义自己的引用计数方案。此类实现不应调用继承的方法;也就是说,它们不应该包含对超级用户的发布消息

哦,我不愿意做那个主意。。基本上:

-(oneway void)release{
    if ([self retainCount] == 1) {
        //This will increment retain count by adding self to the collection.
        [[MyClassBank sharedBank] doneWithItem:self];
    }
    [super release];
}
这样做安全吗

PS:很抱歉发了这么长的帖子,我想把整个想法弄清楚

编辑:

alloc
allother重写并添加
[[MyClassBank sharedBank]getReusableItem]怎么样有吗?

建议的方法: 你在玩参考计数系统。99.99999999999999%的时候这是个坏主意。我强烈建议采用不同的机制。也许这些对象可以实现自己的引用计数,它独立于
retainCount
?然后,您可以使用该referenceCount来实际控制对象何时准备好重用或不重用

不建议的方法: 如果出于某种奇怪的原因,您不能这样做,那么您可以做以下事情,这仍然是一个坏主意,我不建议您实际使用

您可以覆盖
dealloc

- (void)dealloc {
  [ivar release], ivar = nil;
  [anotherIvar release], anotherIvar = nil;
  somePrimitive = 0;
  // do not call [super dealloc]
}

- (void)_reallyDealloc {
  [self dealloc];  // clean up any ivars declared at this level
  [super dealloc]; // then continue on up the chain
}
基本上,
dealloc
方法将是对象准备好重用的点。当您完全处理完对象并最终希望它离开时,您可以使用
\u reallydelaloc
方法在链的上游继续,最终导致对象被释放

请不要这样做。有了自动引用计数之类的功能,这将向您介绍一个充满伤害和非常奇怪的调试场景的世界。很多工具、类和其他东西都依赖于引用计数机制,以便在不进行更改的情况下工作,所以使用它通常不是一个好主意™.

对于觉得这种方法有趣/有用的ppl来说,这里有一种比调用
[super dealloc]更干净的方法直接(这绝对不好)

通过调用
[[Bank sharedBank]purgeBank],将标志设置为true,然后从NSSet中删除所有对象

适应的解决方案:


@Joe Osborn提出了使用类别实现
returnToBank
方法的想法

这正是我想说的。我唯一的补充,一个可能的“没有真正建议”的第三种方法:如果你绝对必须使用你自己的内存管理模型,并且感觉你必须覆盖<代码>发布< /代码>,你可以考虑在 RealtCalue< /Cord>属性上使用关键值。我猜对象可以观察自己的
重新计数
。通过这种方式,至少您不会弄乱像
release
这样的方法的实现。对不起,我没有完全理解您推荐的实现我自己的引用计数的方法,或者您没有注意到我的问题是当NSArray调用对象上的release时:)。。唯一的方法是覆盖release或dealloc,如您所述。但是你不会推荐任何?@Mazyod如果你必须这样做,那么通过
dealloc
方法比
release
方法要安全一些,特别是因为新的ARC功能完全绕过
release
来使用较低级别的运行时函数。顺便说一句,我会直接用这种方式调用[super dealoc],从调用\u reallydalloc:S。。这不是很糟糕吗?另一个选择:你可以考虑一个类的类在一个问题类的方法,如代码> -RetotoBooto<代码>。这样,您就可以使用像
removeAllObjects
这样的习惯用法,而不必担心这种
retain
/
release
devilry。这是我第一次了解对象池模式:有兴趣了解我的情况的人,请阅读:我想使用两个作为自定义类实例的对象。一个是直接使用[pool getReusableObject];然后[object returnToPool]。。然而,另一个是皮塔。我花了两天时间试图对它进行建模,因为该对象有一个指向父对象的指针和一个来自同一类的子对象数组,更不用说它存在于到处都是的数组和IVAR中。。。是的,皮塔。。我花了整整5分钟来实现上面的删除答案,NSlogs显示它工作得非常完美。。。。。。
- (void)dealloc {
  [ivar release], ivar = nil;
  [anotherIvar release], anotherIvar = nil;
  somePrimitive = 0;
  // do not call [super dealloc]
}

- (void)_reallyDealloc {
  [self dealloc];  // clean up any ivars declared at this level
  [super dealloc]; // then continue on up the chain
}
//BAD!
//-(void)dealloc{
//  for some reason, the retainCount at this point == 1
//  if (![[BankStep sharedBank] purgeFlag]) {
//      [self resetObject];
//      [[BankStep sharedBank] doneWithItem:self];
//  } else {
//      [children release];
//      [super dealloc];
//  }
//}