Повторное использование объектов NSO путем переопределения выпуска в Obj-C - PullRequest
2 голосов
/ 04 июля 2011

Я реализую схему повторного использования объектов с использованием одноэлементного класса.

В основном я делаю:

MyClass* obj = [[MyClassBank sharedBank] getReusableItem];

Банк - это всего лишь NSMutableSet, настроенный для оптимального повторного использования.Когда я счастливо реализовывал этот синглтон, я имел в виду, что я просто сделаю следующее, когда я закончу с «obj»:

[[MyClassBank sharedBank] doneWithItem:obj];

В настоящее время мой код будет работать, если я буду использовать его где-тоКстати, но позже я понял, что иногда я добавляю «obj» к «NSCollection», а иногда я звоню:

[theCollection removeAllObjects];

Сначала я думал о создании своего собственного класса, который состоит из коллекции, затемЯ бы перебрал объекты в коллекции и вызвал бы:

[[MyClassBank sharedBank] doneWithItem:obj];

Но это слишком много хлопот, не так ли?

В мой разум пришла хорошая идея (я думаю), который должен переопределить: -(oneway void)release;, поэтому я сразу же перешел к документации Apple, но застрял в следующем:

Этот метод можно реализовать только для определения собственной схемы подсчета ссылок.Такие реализации не должны вызывать унаследованный метод;то есть они не должны включать сообщение о выпуске для super.

Ao, я неохотно делал эту идею .. в основном:

-(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 alltogther и добавить [[MyClassBank sharedBank] getReusableItem]; туда?

Ответы [ 2 ]

4 голосов
/ 04 июля 2011

Предлагаемый метод:

Вы играете с системой подсчета ссылок. 99.9999999999999999% это плохая идея. Я очень рекомендую перейти с другим механизмом. Возможно, эти объекты могли бы реализовать свой собственный счетчик ссылок, который не зависит от 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 будет точкой, в которой объект готов к повторному использованию. Когда вы полностью покончили с объектом и, наконец, хотите, чтобы он исчез, вы можете использовать метод _reallyDealloc для продолжения вверх по цепочке, что в конечном итоге приведет к освобождению объекта.

ПОЖАЛУЙСТА не делайте этого. С такими вещами, как автоматический подсчет ссылок, вы познакомитесь с миром болезненных и действительно странных сценариев отладки. партия инструментов, классов и прочего зависит от механизма подсчета ссылок, который будет работать без изменений, поэтому использование его обычно не является хорошей идеей ™.

0 голосов
/ 04 июля 2011

Для людей, которые считают этот подход интересным / полезным, Вот более чистый способ, чем прямой вызов [super dealloc]; (что, безусловно, плохо)

//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];
//  }
//}

путем вызова [[Bank sharedBank] purgeBank];, установитеустановите значение true, затем удалите все объекты из NSSet.

Адаптированное решение:

@ Джо Осборн: идея использования категорий для реализации returnToBank метода!

...