WedX - журнал о программировании и компьютерных науках

Объекты CF против объектов NS

Я пытаюсь понять, почему существуют объекты CF и NS, которые, кажется, делают одно и то же и взаимозаменяемы через бесплатное соединение. Если, скажем, CFArray и NSArray делают одно и то же, и я могу свободно переключаться между ними, какой смысл в их существовании обоих? Существуют ли эмпирические правила о том, когда использовать один над другим? Являются ли объекты CF просто устаревшими объектами из старых фреймворков? Любое понимание этого будет высоко оценено.

19.02.2012

  • Следует отметить, что а) не все типы CF имеют эквивалент NS и наоборот, и б) не все имена, имена которых совпадают, за исключением префикса, на самом деле соединяются бесплатно; CFBundle и NSBundle, например, нет. Подробнее в документах как всегда. 20.02.2012

Ответы:


1

Чтобы ответить на ваши вопросы по порядку:

  1. Какой смысл в том, что они оба существуют? Есть несколько причин.

    Если вы хотите предоставить C API, такой как Carbon API, и вам нужны такие вещи, как массивы и словари объектов с подсчетом ссылок, вам нужна библиотека, такая как Core Foundation (которая предоставляет CFArray), и, конечно же, она должна иметь C API.

    Если вы хотите написать библиотеки для сторонних разработчиков для использования в Windows (например), вам необходимо предоставить C API.

    Если вы хотите написать низкоуровневую библиотеку, скажем, для взаимодействия с ядром вашей операционной системы, и вам не нужны накладные расходы на обмен сообщениями Objective-C, вам нужен C API.

    Так что это веские причины для использования Core Foundation, чистой библиотеки C.

    Но если вы хотите предоставить более высокий уровень и более приятный API в Objective-C, вам нужны объекты Objective-C, представляющие массивы, словари, объекты с подсчетом ссылок и так далее. Итак, вам нужен Foundation, который представляет собой библиотеку Objective-C.

  2. Когда следует использовать тот или иной? Как правило, вы должны использовать классы Objective-C (например, NSArray) всякий раз, когда можете, потому что интерфейс Objective-C более приятен в использовании: myArray.count (или [myArray count]) легче читать и писать, чем CFArrayGetCount(myArray). Вы должны использовать Core Foundation API только тогда, когда это действительно необходимо: когда вы работаете на платформе, на которой нет Objective-C, или когда вам нужны функции, которые предоставляет Core Foundation API, но отсутствуют объекты Objective-C. Например, вы можете указать обратные вызовы при создании CFArray или CFDictionary, которые позволяют хранить объекты без подсчета ссылок. Классы NSArray и NSDictionary не позволяют вам сделать это — они всегда предполагают, что вы храните объекты с подсчетом ссылок.

  3. Являются ли объекты CF просто устаревшими объектами? Нисколько. На самом деле, Nextstep существовал в течение многих лет только с библиотекой Objective-C Foundation и без (общедоступной) библиотеки Core Foundation. Когда Apple нужно было поддерживать как Carbon API, так и Cocoa API поверх одних и тех же средств операционной системы более низкого уровня, они создали (или обнародовали) Core Foundation для поддержки обоих.

Между прочим, часть Core Foundation имеет открытый исходный код. Вы можете найти его часть с открытым исходным кодом для Mac OS X 10.10.5 здесь: https://opensource.apple.com/source/CF/CF-1153.18/. Я нашел исходный код CFRunLoop и CFStream очень информативным.

19.02.2012
  • Отличное резюме, Роб. Спасибо! 20.02.2012

  • 2

    Core Foundation — это C API для множества общих структур данных. У большинства этих структур данных есть эквиваленты в Cocoa, но не у всех. Большинство из эквивалентных являются бесплатными мостами, что позволяет использовать их взаимозаменяемо, но не все из них.

    Бесплатный мост - это очень хитрый прием. Если вам нужны подробности, см. запись ridiculous_fish, на которую указывает @Matt Wilding. Это наиболее авторитетный источник информации по этому вопросу (и он оказал большое влияние на главу 19 iOS:PTL, в которой также объясняется, как все это работает). Но это не имеет большого значения для большинства целей. Как отмечает Мэтт, обычно можно представить, что NSArray — это то же самое, что CFArrayRef. Во многих случаях это не совсем так, но иногда это так, и в большинстве случаев достаточно близко. Это то же самое, что сказать, что @"stuff" совпадает с NSString, содержащим stuff. В основном это правда, но не совсем так.

    Когда OS 9 перешла на OS X, было очень удобно предоставлять C доступ к структурам данных, подобным Objective-C. Сегодня многие низкоуровневые фреймворки предоставляют C API из соображений производительности. Вы не должны думать о CF как о «устаревшем» или «внутреннем». Вы должны думать об этом как о низкоуровневом, и вы должны использовать его только тогда, когда вам нужна мощность, которую он предоставляет, или вы имеете дело с низкоуровневой структурой, которая требует этого.

    Объекты CF часто более гибкие, чем их аналоги NS. Например, CFDictionaryRef может содержать необъектные ключи и значения, а NSDictionary — нет. (Конечно, они соединяются бесплатно, так что вы можете создать CFDictionaryRef без удержания, а затем рассматривать его как NSDictionary. Хитрость....)

    По мере того как Apple выпускает новые платформы, вы заметите, что они часто сначала раскрывают API-интерфейсы C, а затем добавляют API-интерфейсы Objective-C. Это причина, по которой полезно изучить Core Foundation, даже если вы не используете его каждый день. Но когда это возможно, вы обычно должны использовать ObjC.

    19.02.2012
  • Роб, отличное объяснение. Вы подняли вопрос, который мне показался интересным. В чем разница между @string и NSString, содержащим строку? Я думал, что @string находится в неявном NSString... 20.02.2012
  • @string на самом деле является __NSCFConstantString, который является (своего рода) подклассом NSString. (Отчасти потому, что это бесплатный мостовой класс, который не совсем то же самое, что и подкласс.) Константные строки находятся в сегменте __TEXT, а не в куче (вместе с лежащей в их основе cstring, которая хранится отдельно) и они игнорируют вызовы retain и release. 20.02.2012

  • 3

    У этого вопроса есть история. Core Foundation — это мозг операции. Он написан в основном на C. Он был создан с приобретением Apple NEXT и их API и многим им обязан. Классы NS* часто представляют собой просто абстрактные интерфейсы Objective C, построенные поверх типов CF*. Итак, когда вы спрашиваете, почему существуют и CFArray, и NSArray, ответ заключается в том, что на самом деле их нет. NSArrays являются CFArrays, NSStrings являются CFStrings и т. д. Вот почему возможно бесплатное соединение.

    Для более интересного и подробного чтения я бы отослал вас к этой записи в блоге.

    19.02.2012

    4

    CF означает CoreFoundation. Открытые объекты с CF в именах являются обычными объектами Core Foundation, написанными на C. Все объекты связаны бесплатным мостом со своими друзьями Cocoa Touch Foundation в стране Objective-C. Обычно это непрозрачные указатели.

    NS означает NextStep, старую ОС, на которой была построена Mac OS X. Объекты с префиксом NS обычно полностью написаны на Objective-C или C или даже на C++.

    Это действительно зависит от того, что вам нужно, чтобы каждый объект делал. Мне, конечно, проще работать на чистом Objective-C с NSString, чем на смеси C и Objective-C с CFString, но есть некоторые вещи, которые объекты CF могут делать, а объекты NS просто не могут. t (в основном вещи очень низкого уровня). Объекты CF также гораздо больше балуются ссылками, мутациями и проверками, чем их аналоги NS.

    (Для справки в будущем существует еще несколько префиксов: CG для CoreGraphics, UI для UIKit, QL для QuickLook, AV для AVFoundation, MP для MediaPlayer, MF для MessageFoundation, GL для GLKit и MK для MapKit) (если я пропустил, с удовольствием отредактирую).

    19.02.2012
  • Этот ответ в основном правильный, но может создать некоторую путаницу. Core Foundation не использует объекты на основе Objective C. В некоторых случаях объекты Cocoa реализуются с использованием объектов Core Foundation, но никогда наоборот. Приложения Cocoa должны связывать CoreFoundation.framework. Приложениям Core Foundation не нужно связывать Foundation.framework (который предоставляет NSString и его друзей ObjC). Я также не стал бы называть CF внутренними объектами Apple. Они представляют собой полноценный общедоступный API и обычно используются с другими базовыми платформами, такими как Core Text. Как вы говорите, обычно вы должны использовать NS, если вам не нужен CF. 20.02.2012
  • Что вы имеете в виду, когда говорите, что объекты CF размещаются статически? 20.02.2012
  • Вам не нужен * при их написании: я могу написать CFStringRef ref; без проблем 20.02.2012
  • @CodaFi, это потому, что CFStringRef - это просто непрозрачный указатель. Фактические экземпляры CFString должны быть динамически распределены, как и все остальное. 20.02.2012
  • Я думал, что большинство объектов C были размещены статически (или я могу просто спутать их с C++)? 20.02.2012
  • @CodaFi, на самом деле нет таких объектов, как объекты C. Существуют структуры C и функции, которые работают с ними, и если вы приложите усилия, чтобы скрыть фактическое определение структуры C с помощью непрозрачного указателя, вы можете создать иллюзию объектов C. Это то, что Apple делает с типами CF*, и именно поэтому вы всегда должны передавать CFRef всем функциям CF. Однако объекты C++ можно создавать в стеке, так что, вероятно, вы так думаете. 20.02.2012
  • Новые материалы

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

    Учебные заметки: создание моего первого пакета Node.js
    Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

    Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
    Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..

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


    Для любых предложений по сайту: [email protected]