2013-12-26 2 views
2

Рассмотрите ситуацию, реализованную в Manual Retain Release, где у меня есть переменная, указывающая на объект, возвращаемый методом.Нужно ли сохранять объект, возвращенный методом в не-ARC?

{ 
    ... 
    NSString *str = [self myNewString]; 
    ... 
} 

- (NSString *)myNewString 
{ 
    NSString *myString = [NSString stringWithFormat:@"%d-String", 1]; 
    return myString; 
} 

Здесь мы должны сохранить объект, возвращаемый myNewString так, что оно не будет выпущен в то время как мы используем его?

Пожалуйста, помогите, я новичок в Objective-C. Заранее спасибо.

+1

Если вы просто изучаете Objective-C, изучите ARC вместо этого. Ручной подсчет ссылок - это еще одна вещь, которую вы можете ошибаться, и она абсолютно ничего не покупает. – godel9

+1

Да, спасибо за совет. Но я увлекаюсь пониманием того, что на самом деле происходит под капотом. Поэтому я начал изучать счетчик ссылок вручную. – user3008132

+0

Замечательно, что вы хотите развить глубокое понимание Objectivr-C, но я настоятельно призываю вас снова изучить Modern Objective-C/ARC. Он подчеркивает отношения между объектами, а не механический и автоматизированный подсчет ссылок. – godel9

ответ

4

Есть два аспекта этого ответа:

  1. Во-первых, вы хотите, чтобы соответствовать правилу метод присвоения имен, которые диктуют, что любой метод, имя которого начинается с «Alloc», «новый», «копия »Или« mutableCopy »должен иметь счет сохранения +1 (т. Е. Право собственности переносится), в противном случае это должен быть объект autorelease (или, точнее, любой объект, чье право собственности не передано, и если вызывающий абонент хочет заявить право собственности, он должен был бы вручную retain).

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

    Независимо от этого правила именования этого метода включены в Basic Memory Management Rules, изложенные в Руководстве по программированию памяти с расширенным управлением памятью .

    Итак, в ручном удержании и выпуске у вас есть один из двух вариантов. Если метод начинается с «Alloc», «новый», «копия», или «mutableCopy», то он должен передать в собственность, возвращая +1 retainCount объект, например:

    - (NSString *)newSomeString 
    { 
        return [[NSString alloc] initWithFormat:@"%d-String", 1]; 
    } 
    

    в противном случае, он не должен передавать владение (например,возвращать autorelease объект), например:

    - (NSString *)someString 
    { 
        return [NSString stringWithFormat:@"%d-String", 1]; 
    } 
    
  2. Таким образом, если абонент хочет, чтобы убедиться, что объект был сохранен, он может либо просто вызвать метод, который возвратил +1 объект:

    NSString *string = [self newSomeString]; 
    

    или вызвать версию, которая возвращает autorelease объект, но затем явно retain это:

    NSString *string = [[self someString] retain]; 
    

На практике последнее соглашение, пример someString, является более распространенным (использовать метод, который возвращает объект autorelease, т. Е. Где имя метода не начинаются с «alloc», «new», «copy», mutableCopy»; а затем, если вызывающему абоненту должно быть retain, оно должно просто явно сделать это). Методы new, copy и mutableCopy все они обычно используются в соответствующих очень специфических контекстах, которые здесь не применяются.

Кстати, если вы запустите свой код через статический анализатор («Анализируйте» в меню «Продукт» Xcode), то замечательно хорошая работа предупреждает вас, если ваш код MRR имеет проблемы с сохранением объектов или сбоем сохраните их.

Но нижняя линия, внимательно следить за basic memory management rules, в том числе конвенции о методах именования, а затем, если вам это нужно сохранить, явно retain ваш autorelease объект или вызвать метод, который возвращает +1 retainCount объекта.

+0

Это делает меня более ясным. В случае, если я создал строку с использованием alloc, мне не нужно сохранять ее при приеме. Но если я создал его с помощью любого метода класса, такого как stringWithFormat, мне нужно будет его сохранить, чтобы он работал до тех пор, пока я его не попрошу. Я получил это правильно @Rob? – user3008132

+0

@ пользователь3008132 Да, это в основном правый. А также убедитесь, что имя вашего метода соответствует типу возвращаемого объекта (например, имя метода запуска с «alloc», «new», «copy» или «mutableCopy», если это объект return +1, созданный с помощью 'alloc'/'init'; не начинайте метод с одной из этих четырех строк, если вы возвращаете объект' autorelease', например объект, созданный с помощью 'stringWithFormat'). В этом случае я бы посоветовал метод под названием 'someString' (или что-то еще), который возвратил объект, созданный с помощью' stringWithFormat', и вызывающий вызывал его вручную. – Rob

+0

Большое вам спасибо. Это очень помогло мне. – user3008132

0

Здесь вы передаете только адрес места, где хранится объект NSString. Таким образом, определенный объект будет сохранен компилятором. Но вам не нужно беспокоиться. ARC будет заботиться о рилизинг памяти после того, как счетчик ссылок 0. Держи Learn more about ARC

+0

Привет, я редактировал свой вопрос. Моя ситуация в том случае, когда я использую ручной подсчет ссылок, а не ARC. Спасибо. – user3008132

+0

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

+0

Эй. Я не понимал, почему вы приняли другой ответ. Как вы сказали, вы искали ручную подсчет ссылок. Другие ответы на вопросы о ARC .. Пожалуйста, подтвердите это снова и дайте мне знать, если я ошибаюсь –

0

В принципе любой метод, который возвращает новый объект, кроме new/alloc + init возвращает его без собственности, а это означает, что вы можете рассчитывать на это прилипание вокруг до тех пор, пока окружающий авторефлектор не сохнет, но после этого ничего не сказал. Если вы хотите сохранить его дольше, вы должны сохранить его.

+0

Извините, но этот ответ недействителен для ручной подсчета ссылок. Как ясно упоминается в вопросе, человек говорит о ручном подсчете ссылок. –

+0

@achievelimitless Если вы считаете, что этот ответ не является полезным или явно неправильным, вы должны понизить его, вместо того, чтобы помечать его как «не ответ». –

+0

Извините @jack .. не хватает репутации, чтобы проголосовать за него :( –

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