2

Когда метод экземпляра возвращает значение, которое было инициализировано конструктором удобства, мне нужно сохранить этот объект, а затем автоопределение в возврате, чтобы при возникновении авторекламы удобства конструктора Не удаляйте объект.Возвращаемый объект, инициализированный с помощью «конструктора удобства»

Будет ли это описание выпуска до вызова кода и взять на себя ответственность с сохранением или чем-то еще?

- (NSStringMutable *)test { 
    NSMutableString *description = [NSMutableString stringWithString:@"Test Value"]; 
    return description; 
} 

Или должно быть так?

- (NSStringMutable *)test { 
    NSMutableString *description = [NSMutableString stringWithString:@"Test Value"]; 
    [description retain];        
    return [description autorelease]; 
} 

Телефонный код:

NSMutableString *testVar = [[NSMutableString alloc] initWithString:[object description]]; 

ответ

9

Нет, вы должны быть хорошо с:

- (NSStringMutable *)test 
{ 
    return [NSMutableString stringWithString:@"Test Value"]; 
} 

Это оставит объект с сохранением графом 1 и будет в autorelease бассейне.

Пульт автореферата осушен в определенное время - это не похоже на сборщик мусора. Если вы реализуете обработчик событий (например, обработчик с щелчком мыши), пул автозапуска сбрасывается каркасом при возврате из кода обработки событий.

Если вы использовали это:

- (NSStringMutable *)test 
{ 
    NSMutableString *description = [NSMutableString stringWithString:@"Test Value"]; 
    [description retain];                
    return [description autorelease]; 
} 

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

+0

+1 Это отвечает на вопрос – Abizern

+2

Вы верны, но старайтесь избегать разговоров об удержании подсчета, это красная селедка - нет никакой гарантии, что NSMutableString вернет автореализованный объект, только если он вернет изменчивую строку, которую вы в настоящее время нет. Вы можете безопасно вернуть результат вызывающему только потому, что правила управления памятью явно указывают: «Этот метод также может безопасно вернуть объект его вызывающему».

+2

Это хороший момент. Я считаю, что мышление с точки зрения количества накоплений полезно для объяснения вещей. Вы правы - все, что вы знаете, это то, что stringWithString возвращает объект, принадлежащий кому-то другому. В этом случае, поскольку NSMutableString фактически назначил объект, это обязанность NSMutableString освободить его. Я был под впечатлением, что эти конструкторы удобства (конструкторы non-init) обычно возвращают объекты с автореализацией. Я был бы удивлен, если бы натолкнулся на того, кто не вел себя так. –

0

Нет, вы можете просто вернуть autoreleased значение. Причина этого заключается в том, что автореферат не является функцией самой переменной, она является функцией пула автозапуска, который (если вы не создаете его самостоятельно) обычно управляется циклом запуска.

0

Вы находитесь рядом со вторым, но вам не нужно сохранять для случая, о котором вы говорите, и на самом деле вам не нужно самостоятельно звонить авторекламу.

Это справедливо, так как stringWithString возвратит autoreleased объект уже:

- (NSStringMutable *)test 
{ 
    return [NSMutableString stringWithString:@"Test Value"];   
} 

В целом при создании объектов с помощью Objective-C, если вы вызываете конструктор удобства (не вызывая Alloc и инициализации) возвращаемое значение всегда автореализован, поэтому stringWithString возвращает объект с автореализацией, который вы можете просто вернуть.

1

Вы можете просто вернуть его. Это одна из основных целей автореферата. Если вы не создали собственный пул автозаполнения, пул не будет слит до следующего прогона цикла событий. memory management programming guide подробно объясняет это - вы должны прочитать это, пока не почувствуете себя комфортно.

Сторона примечания: Если это не было безопасным, и пул авторефератов должен был быть истощен рано по какой-то причудливой причине, давая ему два зачета, а два авторелеаза не повлияли бы. Цифры все еще сбалансированы, поэтому в какой-то момент он все равно будет выпущен.

1

Я уже проголосовал на правильный ответ, я добавляю это как стиль примечание:

Ваш вызывающий код не будет работать, потому что он звонит [object description], когда он должен называть [object test]

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

Вы могли бы переписать это так:

-(NSString *)description { 
    // Just return a static NSString. No need to worry about memory management. 
    return @"Test Value"; 
} 

И если вы хотите, чтобы иметь возможность изменить значение этого возвращается строка в вашем Телефонный код:

NSMutableString *testVar = [[NSMutableString alloc]initWithString:[object description]]; 

Поскольку вы назвали Alloc на этой строке, вы являетесь его владельцем, и несут ответственность за освобождение ее в какой-то дату в будущем.

В качестве альтернативы, вы можете использовать один из моих любимых битов кода:

NSMutableString *testVar = [[object description] mutableCopy]; 

Это вернет изменяемую копию даже неизменного объекта (если оно соответствует протоколу NSMutableCopying, конечно). И вам нужно отправить [testVar release] на каком-то этапе.

И связать это в качестве действительного ответа на ваш вопрос: если вы отправите Alloc, копию, mutableCopy или сохраняют к объекту, то у вас есть объект, и несут ответственность за отправку это выпуск сообщение. Вы можете предположить, что что-либо еще возвращает объект с автореализацией.

Опять же, я знаю, что это всего лишь короткий пример кода, на который вы задавали вопрос, но если вы будете следовать приведенному выше правилу, у вас будет устранена большая часть проблем с управлением памятью. В первом примере вы не отправили ни одного из них для сообщений, поэтому вам не нужно выпускать какую-либо память самостоятельно. Однако у вас есть код alloc в вашем кодовом коде, поэтому вы владеете testVar, и вам нужно его освободить.

+0

Спасибо за ввод. Я не знал о mutableCopy.Вы правы, что это всего лишь пример для моего вопроса. Спасибо за проработку. Я довольно новичок в объекте c, и даже не вернул NSString, который я могу передать initWithString для NSMutableString. Спасибо за информацию. – Brian

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