2009-08-18 4 views
3

Если я выделил объект в методе «getASprocket» и назвал его таким образом, будет ли здесь утечка?Управление памятью и производительность

Sprocket *sprock = [Sprocket getASprocket]; 

// store this returned value as an ivar 
ivarSprock = [sprock retain]; 

// release the originally acquired object 
[sprock release]; 

Объект Звездочка выделяется и возвращается таким образом:

– (Sprocket *)getASprocket { 
    Sprocket *sprocket; 

    sprocket = [[Sprocket alloc] init]; 

    return [sprocket retain]; 
} 

Кроме того, будет изменяющийся от '[sprocket retain];' внутри метода «aSprocket», чтобы 'return [sprocket autorelease];' сделать хуже потери производительности?

+0

Похоже, вы сделали опечатку; «-» должен быть «+», поскольку вы используете его как метод класса, а не метод экземпляра. – Michael

+0

@Michael, в то время как ваш комментарий верен, в большинстве случаев это технически корректно даже с "-" –

ответ

0

Пожалуйста, смотрите эту хорошее объяснение страница Especially sub-page #7

каждый сохраняют создал другой объект памяти.так что давайте посмотрим, что у нас есть:
в getASprocket:

sprocket = [[Sprocket alloc] init]; 

+1

return [sprocket retain]; 

+1

и на вашем методе:

ivarSprock = [sprock retain]; 

+1

[sprock release]; 

-1

Что мы должны делать? Ну мы должны позволить Sprock идти, делая его autorelease:

return [[[Sprocket alloc] init] autorelease] 

или в словах обозначаемой ссылки выше:

В большинстве случаев сеттера для переменного экземпляра нужен просто autorelease старого объекта и сохранить новый. Затем вы просто убедитесь, что выпустили его и в dealloc.

0

Возможно, вы должны прочитать memory management guide. Это недолго, и это очень здоровое чтение.

Что касается вашего конкретного случая, в getASprocket следует изменить:

return [sprocket retain]; 

к:

return [sprocket autorelease]; 

, так как абонент метода не должен быть ответственным за отпуская объект (если он не сохраняет он сам, очевидно).

Кроме того, речь идет не о производительности вообще - это все управление памятью.

0

Все это действительно вызывает утечки. Так что давайте перейдем к подсчету ссылок вашего звездочки, в getASprocket вы говорите, что Sprocet alloc увеличивает счет, а затем сохраняет, что увеличивает его снова, вы на +2 здесь, а затем в первом фрагменте кода, который вы сохраняете снова +3 , а затем выпустите +2, вы пропустили объект с подсчетом ссылок +2. Что вы можете сделать МЕЕТСЯ

-(Sprocket*)getASprocket) 
{ 
    return [[[Sprocket alloc] init] autorelease] 
} 

это держит количество ссылок на 0

0

Там в течи в вашем getASprocket: метод.

sprocket = [[Sprocket alloc] init]; 
return [sprocket retain]; 

Вы сохраняете звездочку дважды, один раз с alloc/init и один раз с сохранением, что вы не хотите делать. Используйте

return [sprocket autorelease]; 

быть Также обязательно установите iVarSprock на ноль, прежде чем выпустить звездочку или это будет указывать на какую-то оперативную память.

0

В то время как технически неверно, метод getASprocket очень отличается от типичного развития какао и какао-Touch. Если у вас нет дополнительной логики в методе, вы бы лучше сделать это:

ivarSprock = [[ Sprocket alloc ] init ]; 

// Other Code Here 

[ ivarSprock release ]; 
0

Как и в сторону, если вы беспокоитесь о производительности в приложении, то, что вы должны смотреть на первую и Прежде всего, это алгоритмы, которые вы используете для реализации своего программного обеспечения. Это, прежде всего, то, что улучшит производительность. Только после того, как вы внедрили сильные алгоритмы, если вы (если вам нужно) вернитесь назад и взгляните на более мелкие заботы.

0

Учитывая то, как вы написали свой метод, на самом деле существует утечка в вашем коде. Вы хотели бы написать это (в противном случае «Sprock» заканчивается сохранить кол 1, и, следовательно, не dealloc'd):

+ (Sprocket *)getASprocket 
{ 
    return [[[Sprocket alloc] init] autorelease]; 
} 

Сохранить отсчеты действительно очень просто, как только вы получите повесить Это. Просто следуйте этим правилам:

  • объектов, созданных alloc или copy имеют сохранить кол 1 (и должен быть освобожден)
  • Предположим, все остальные объекты имеют сохранить кол 1, но autoreleased (как выше метод)
  • Retain объекты, которые вы хотите, чтобы держать вокруг
  • Release объектов, когда вы больше не заинтересованы в них (никогда вызов dealloc себя)

Использование пулов автоопределения имеет небольшое влияние на производительность, но это просто делает вещи намного проще, потому что вам не нужно знать внутренние детали реализации каждого метода.

Смежные вопросы