Правильное использование CFStringTokenizerCreate с ARC? - PullRequest
0 голосов
/ 24 марта 2012

У меня есть кусок кода, который преобразователь ARC превратил в это ...

// firstRange is a NSRange obviously
// test is an NSString * passed in as parameter to the method
NSRange range = NSMakeRange(firstRange.location, (lastRange.location - firstRange.location) + lastRange.length);
NSString *sentence = [text substringWithRange:range];
// OK, now chop it up with the better parser
CFRange allTextRange = CFRangeMake(0, [sentence length]);
CFLocaleRef locale = CFLocaleCopyCurrent();
CFStringTokenizerRef tokenizer = CFStringTokenizerCreate(kCFAllocatorDefault,
  (__bridge CFStringRef) sentence,
  allTextRange,
  kCFStringTokenizerUnitWord,
  locale);

Я называю это МНОГО и подозреваю, что он как-то протекает.Это вызов CFStringTokenizerCreate кошерный?Я особенно подозрительно отношусь к __bridge.Создаю ли я промежуточное звено, которое я должен выпустить вручную, или какое-то подобное зло?

Ответы [ 4 ]

1 голос
/ 24 марта 2012

Вам нужно позвонить CFRelease(tokenizer);, когда вы закончите с использованием токенизатора. См. Правила владения . Вы должны позвонить CFRelease(locale); тоже.

Ваш синтаксис __bridge sentence правильный. Я должен сказать, что Xcode верен примерно __bridge и __bridge_transfer большую часть времени. В вашем случае вы передаете ссылку на NSObject для использования с CF. У вас нет намерения передавать право собственности CF, поскольку вы считаете, что ARC отлично справляется с управлением объектами NSO. Поэтому, когда CFStringTokenizerCreate завершено с использованием sentence, он ничего не сделает для его освобождения. ARC освободит sentence.

С другой стороны, если вы изменили его на __bridge_transfer, вы сообщаете ARC, что передаете право собственности CF. Поэтому, когда вы закончите, ARC не освободит sentence. Вы должны вызвать CFRelease(sentence);, чтобы освободить его, что не является желательным поведением.

1 голос
/ 24 марта 2012

Вам нужно CFRelease tokenizer и locale, иначе они будут вытекать.

Подпадает под Основную политику владения фундаментом и не имеет ничего общего с ARC.

Приведение __bridge сообщает ARC, что передача sentence в CFStringTokenizerCreate звонка не осуществляется. Так что все в порядке.

Вы можете проверить утечки памяти с помощью статического анализатора и профилировщика Xcode.

0 голосов
/ 19 февраля 2017

Для всех пользователей Swift, читающих эту ветку: функция CFRelease(), по-видимому, не была перенесена на язык Swift, поскольку объекты Core Foundation автоматически управляются памятью (согласно предупреждению компилятора, которое я вижу в Swift 3.0).2), так что об этом нужно думать меньше.

0 голосов
/ 24 марта 2012

Моя интуиция говорит мне, что это должен быть __bridge_transfer вместо bridge, так как вы вызываете create (если только вызов CFRelease позже). Я также думаю, что локаль должна быть выпущена, так как это копия.

РЕДАКТИРОВАТЬ Упс меня игнорируют, я неправильно прочитал (использовал телефон)

...