2011-12-19 6 views
3

Я читал много статей в Интернете, и я немного смущен насчет ARC. Ниже перечислены мои вопросы, пожалуйста, помогите мне ответить на них.ARC и освобождение памяти

1.) Что делает ключевое слово strong (in @property (nonatomic, strong) …)?

2.) Не надо ли нам release или autorelease, что мы alloc больше, потому что я получаю предупреждение о том, что мне не нужно. (Я не на своем Mac, поэтому я не могу скопировать предупреждение, которое я получил.)

3.) Я не смог найти инструмент «Утечки» в Xcode 4.2. Куда он пошел? Или нам не нужно больше проверять утечки?

4.) При создании проекта с использованием Xcode 4.2 я нажал кнопку «включить ARC», и моя программа будет работать на iOS 3? (Я думаю, ARC поддерживает только IOS 4 и выше.)

+1

Пожалуйста отправьте их как отдельные вопросы. – Jim

+0

Я думаю, что все они связаны. – sharon

+0

Ответ Тима очень хороший, но вы все равно должны прочитать документацию для своей собственной выгоды. –

ответ

6
  1. Strong эквивалентно retain в АРК. Он указывает на владение: What does the "strong" keyword do

  2. Нет, это сделано для вас. ARC автоматически вставляет эти инструкции в (скомпилированный) код. Это его основная работа. Но, по словам Абизерна, это работает только для ваших объектов и объектов Cocoa. Если вы используете классы Core Foundation (CF*), тогда вы должны прочитать о семействе отливок __bridge. You might start reading here.

  3. Это в Инструментах. На ответ iHunter, Cmd + I или Product-> Profile, затем выберите «Утечки». Особенно важно данное (2).

  4. Это не сработает.

+1

+1. Что касается № 2, вы не должны получать предупреждение; вы должны получить сообщение об ошибке. Дело не в том, что вам не нужно использовать 'release'. Это значит, что вы * не должны использовать 'release'. –

+0

Так что мы все еще должны испытывать утечки? Если ARC освобождает память, то почему мы должны тестировать утечки? – sharon

+1

ARC занимается только какао-объектами. Если вы используете объекты Core Foundation, вам все равно придется использовать управление памятью. Существуют правила передачи права собственности на объекты при использовании бесплатного моста. ARC не избавляет от управления памятью - это просто делает более общие части этого проще и эффективнее. Итак, да, вам все равно нужно проверить наличие утечек. – Abizern

7
  1. strong является аналогом АРК на retain (нет никакого retain под АРК). Это означает, что значение свойства будет удерживаться классом, где был определен @property и выпущен после переназначения или dealloc. (Обратите внимание, что в ARC нет необходимости выпускать или аннулировать свойства в dealloc).

  2. Пункт ARC позаботится о том, чтобы компилятор выполнял процедуру retain/release, поэтому нет необходимости в ручных методах управления памятью.

  3. Вы можете проверить наличие утечек, запустив профиль (Product -> Profile) и выбрав инструмент «Утечки». Утечки могут быть введены с циклическими ссылками или кодом CoreFoundation (ARC не работает с CoreFoundation). Также, если вы смешиваете ARC и код, отличный от ARC, последний может стать источником утечек.

  4. ARC поддерживается ОС, начиная с iOS 4.0 (хотя требуется SDK для IOS 5). Ключевое различие между поддержкой 4.0 и 5.0 ARC - наличие спецификатора свойства weak. Слабое свойство (__weak variable) будет автоматически сбрасываться, когда значение strong, на которое он ссылается, будет освобождено. В 4.0 нет свойств weak, поэтому должен использоваться спецификатор __unsafe_unretained (это близкий аналог к ​​спецификатору assign, он не сохраняет значение и может указывать на уже освобожденное значение, поэтому он опасен).

Вот большое объяснение АРК: Everything you need to know about automatic reference counting

+0

ARC поддерживается для iOS4.3 и далее - не 4.0. – Abizern

+0

ARC не работает с CoreFoundation, поэтому утечки могут быть введены в CF-код. Также, если вы смешиваете код ARC и не ARC, последний может быть источником. – iHunter

+0

@Abizern Спасибо, я исправил свой ответ – iHunter

2

Ну, уже есть три ответа, которые охватывают основные вещи, поэтому я остановлюсь на одной детали здесь, что уже не упоминаются:

3.) Я не нашел инструмент «Утечки» в Xcode 4.2. Куда он пошел? Или нам не нужно больше проверять утечки?

Да мы все еще нужно проверить на наличие утечек:

ARC не мусора, она автоматизирована сохранить/релиз.

Таким образом, все еще возможно - на самом деле, это довольно просто - создать утечки!

Рассмотрим следующий пример:

@class Puppet; 
@protocol PuppetDelegate : <NSObject> 
- (void)puppetDidTwistStrings:(Puppet *)puppet; 
@end 

@interface Puppet : NSObject { 
    id <PuppetDelegate> delegate_; 
} 

- (id)initWithPuppetDelegate:(id <PuppetDelegate>)delegate; 
- (void)unravelStrings; 

@end 

@implementation Puppet 
- (id)initWithPuppetDelegate:delegate 
{ 
    if (!(self = [super init])) return nil; 

    delegate_ = delegate; 

    return self; 
} 

// assume some implementation for unravel strings 

@end 

@interface MasterOfPuppets : NSObject <PuppetDelegate> { 
    NSMutableArray *puppets_; 
} 

- (void)puppetDidTwistStrings:(Puppet *)puppet; 
- (void)bringOutAPuppet; 

@end 

@implementation 
- (id)init 
{ 
    if (!(self = [super init])) return nil; 

    puppets_ = [[NSMutableArray alloc] init]; 

    return self; 
} 

- (void)bringOutAPuppet 
{ 
    Puppet *newPuppet = [[Puppet alloc] initWithPuppetDelegate:self]; 
    [puppets_ addObject:newPuppet]; 
} 

- (void)puppetDidTwistStrings:(Puppet *)puppet 
{ 
    BOOL isOurPuppet = [puppets_ containsObject:puppet]; 
    if (!isOurPuppet) return; 

    [puppet unravelStrings]; 
} 
@end 

Этот пример является (по общему признанию) немного глупый, но этот код будет течь, и ARC не собирается, чтобы помочь вам об этом, в то время как вывоз мусора будет:

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

Если в не-ARC кода переменной экземпляра просто указатель, который был быть назначен, ARC предполагает, что если вы копить что-то в переменной, вы хотите, чтобы цепляться за нее, и она будет retain значение, если только вы скажите это не.

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

Это может показаться надуманным и надуманным примером, но это не так: я видел это довольно много в отношениях делегатов.

(Решение, кстати, довольно просто: объявить переменную delegate_ экземпляра Puppet «s, как weak и все работает как надо.)

+0

Честно говоря, эта проблема (протекание циклических ссылок) существует даже в средах GC. GC не может решить, какая ссылка для первого разрыва. – iHunter

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