#pragma mark в Swift?


936

В Objective C я могу использовать #pragma markдля маркировки разделов моего кода в навигаторе символов. Так как это команда препроцессора C, она не доступна в Swift. Есть ли замена для этого в Swift, или я должен использовать уродливые комментарии?


15
Это действительно важно для организации нашего длинного кода.
iPatel

Похоже, что быстро заметной разницы между комментариями и разметкой разделов больше нет. Расширения не названы, поэтому кажется, что отдельные файлы - единственный способ провести различие между двумя типами комментариев
Стивен Дж.

1
Вы можете проверить это: stackoverflow.com/a/33040068/1753005
Jayprakash Dubey

1
Для других новичков Swift и Xcode я просто упомяну, что «навигатор символов», о котором все говорят, это тот, который вы получаете, когда нажимаете на самую правую вещь в «панели переходов» в верхней части окна редактирования. Это не символ навигатора на левой панели.
RenniePet

1
@HarshilKotecha Swift - это язык программирования, независимый от платформы, на которой он работает. Знак Pragma является частью Swift и может использоваться на Linux, macOS и других платформах Apple, включая iOS. Было бы смешно отмечать этот вопрос на любой из этих платформ, потому что прагма - это особенность самого Swift, а не платформы. iOS - только одна из многих платформ, на которых работает Swift. Это важно понимать. Этот вопрос не об iOS, и не о Linux или macOS. Это о Свифте.
Эрик Айя

Ответы:


1202

Ты можешь использовать // MARK:


Также было обсуждение, что либеральное использование расширений классов могло бы быть лучшей практикой в ​​любом случае. Поскольку расширения могут реализовывать протоколы, вы можете, например, поместить все методы делегата табличного представления в расширение и сгруппировать ваш код на более семантическом уровне, чем #pragma markэто возможно.


64
И да, новое соглашение для разработчиков позволяет нам говорить об этом материале :)
Фрэнк Шмитт

4
Вы не можете использовать расширения для хранения протокола, который имеет метод init, такой как NSCoding. Это затрудняет разделение, если вы не можете использовать его во всех случаях.
Мэтью Книппен

149
В бета - версии 4, 6 Xcode признает // MARK:, // TODO:и // FIXMEв источнике Swift и перечисляет их в строке перехода. (Кстати, это уже было сделано в (Obj) C-источнике - #pragma markне единственный способ.) И да, вы все равно можете добавить -к своему, MARKчтобы поместить разделители в меню.
Рикстер

17
+1 за рекомендацию расширений. Даже с MARKработой сейчас, использование расширений для группировки некоторых видов семантически связанного кода (особенно реализации протокола) все еще может быть полезным. ИМХО, гораздо лучше читать ваше заявление о соответствии протокола прямо рядом с методами, которые его реализуют, а не 5 объявлений протокола в верхней части файла и 50 реализаций связанных методов, случайно разбросанных где-то ниже.
Рикстер

37
@StevenKramer: так же, как и с #pragma mark. // MARK: -это просто разделитель, // MARK: - stuffдает вам разделитель и заголовок, и // MARK: - stuff -дает вам разделитель, заголовок и другой разделитель все в одной строке комментария.
Рикстер

174

До Xcode 5 #pragma markсуществовала директива препроцессора .

Начиная с Xcode 6, вы должны использовать // MARK:

Эти возможности препроцессора позволяют внести некоторую структуру в раскрывающийся список функций редактора исходного кода.

Некоторые примеры :

// MARK:

-> будет предшествовать горизонтальный разделитель

// MARK: your text goes here

-> ставит «ваш текст идет здесь» жирным шрифтом в раскрывающемся списке

// MARK: - your text goes here

-> в раскрывающемся списке выделяет жирным шрифтом слово «ваш текст», которому предшествует горизонтальный разделитель

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

введите описание изображения здесь


1
В XCode 6.1.1 // MARK: - textдля меня нет разделителей, и в раскрывающемся списке отображается MARK: текст, а не просто текст .
Mostruash

у меня нормально работает в Xcode 6.1.1, я только что добавил скриншот - пожалуйста, уточните свой код?
Ронни Веберс

Я забыл упомянуть, что я пробовал это для файлов Objective-C. Голосование за усилия, хотя, спасибо.
Mostruash

1
Понятно, теперь все ясно :-) Вначале спрашивается о Свифте, поэтому я об этом не задумывался. Для полноты: в Objective-C вы можете сделать то же самое, используя: #pragma mark - здесь идет ваш маркерный текст , или просто #pragma mark - если вам нужна полоса, или #pragma mark Ваш маркерный текст идет сюда, чтобы получить то же самое без бара. (извините, я не могу получить правильную разметку для фрагментов кода, я выделил их жирным шрифтом)
Ронни Веберс

Это немного изменилось в Xcode 8.1, но это правило в целом работает, лучше предпочитаю этот ответ: D
windsound

167

Для тех, кто заинтересован в использовании расширений против прагматических отметок (как упомянуто в первом комментарии), вот как реализовать это из Swift Engineer:

import UIKit

class SwiftTableViewController: UITableViewController {

    init(coder aDecoder: NSCoder!) {
        super.init(coder: aDecoder)

    }

    override func viewDidLoad() {
        super.viewDidLoad()

    }
}

extension SwiftTableViewController {
    override func numberOfSectionsInTableView(tableView: UITableView?) -> Int {
        return 1
    }

    override func tableView(tableView: UITableView?, numberOfRowsInSection section: Int) -> Int {
        return 5
    }

    override func tableView(tableView: UITableView?, cellForRowAtIndexPath indexPath: NSIndexPath?) -> UITableViewCell? {
        let cell = tableView?.dequeueReusableCellWithIdentifier("myCell", forIndexPath: indexPath) as UITableViewCell;

        cell.textLabel.text = "Hello World"

        return cell
    }

}

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


6
Это очень круто, но было бы неплохо, если бы расширения могли иметь имена.
Мэтью Книппен

16
@ Матфея - Вы могли бы использовать typealias. Например typealias DataSource = SwiftTableViewController. Тогдаextension Datasource {}
Логан

1
@PhongLe UITableViewControllerэто не протокол, это класс. Вы, вероятно, имеете в виду UITableViewControllerDataSource, но это не шаблон, используемый в примере.
КПМ

4
Мне просто интересно, почему бы не extensionполучить заголовок с протоколом, например extension SwiftTableViewController : UITableViewController, было бы более понятно, почему вы добавили это расширение в класс.
Holex

7
Обратите внимание, что если ваше расширение существует исключительно для реализации протокола, вы можете назвать расширение: extension SwiftTableViewController : UITableViewDelegate { .. }иextension SwiftTableViewController : UITableViewDatasource { .. }
Крейг Отис

117

Pragma mark - [SOME TEXT HERE]был использован в Objective-C для группировки нескольких функций с помощью разделения строк.

В Swift вы можете добиться этого, используяMARK, TODO OR FIXME

я. ОТМЕТКА : //MARK: viewDidLoad

Это создаст горизонтальную линию с функциями, сгруппированными под viewDidLoad (показано на скриншоте 1)

Снимок экрана 1

II. ДЕЛАТЬ : //TODO: - viewDidLoad

Это сгруппирует функцию под TODO: - категория viewDidLoad (показано на скриншоте 2)

Снимок экрана 2

III. ИСПРАВИТЬ МЕНЯ : //FIXME - viewDidLoad

Это сгруппирует функцию в FIXME: - категория viewDidLoad (показано на скриншоте 3)

Скриншот 3

Проверьте эту яблочную документацию для деталей.


Обратите внимание, что "-" после TODO и FIXME ничего не делают. «-» относится только к директиве MARK.
Ризмай

1
Он также создает большой заголовок раздела с заглавной буквы в коде «миникарта», который можно отобразить в правой части исходного файла. Довольно удобно.
Оскар

66

Официальная документация

Официальный документ Apple о панели переходов Xcode: добавление аннотаций кода в панель переходов

Скриншоты Jump Bar для примера кода

Образец кода

Поведение в Xcode 10.1 и macOS 10.14.3 (Мохаве)

Xcode 10.1 и macOS 10.14.3

Поведение в Xcode 10.0 и macOS 10.13.4 (High Sierra)

Xcode 10.0 и macOS 10.13.4

Поведение в Xcode 9.4.1 и macOS 10.13.0

Xcode 9.4.1 и macOS 10.13.0

обсуждение

!!!:и ???:иногда не могут быть отображены.


!!!: и ???: синтаксис не работает на Xcode 11.3.1
Джайпракаш Дубей

56

В коде Objective-C Xcode обнаруживает такие комментарии, // MARK: - fooкоторые немного более переносимы, чем #pragma. Но они, похоже, тоже не подобраны (пока?).

Редактировать: Исправлено в Xcode 6 beta 4.


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

1
Я могу подтвердить, что // MARK: -на данный момент не работает.
Руи Перес

Не работает, но пример кода изобилует этим стилем комментариев, так что в конечном итоге его нужно подобрать.
Нейт Кук

1
это важно, комментарий должен быть переносимым? потому что перенос кода Swift на любой другой язык напрямую - это уже сложная задача для разработчиков.
Holex

Хм, я вижу, что многие люди комментируют, что это работает, но я на бета-версии 6 и // MARK:, похоже, не работает. Я пробовал с пробелом и без пробела, с двоеточием и без него, все заглавные буквы и смешанный (Марк). Есть ли хитрость? Нужно ли активировать преф или что-то еще?
Оли

37

Я думаю, что Extensionsэто лучший способ вместо #pragma mark.

Код перед использованием Extensions:

class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {
    ...

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        ...
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        ...
    }

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        ...
    }
}

Код после использования Extensions:

class ViewController: UIViewController {
    ...
}

extension ViewController: UICollectionViewDataSource {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        ...
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        ...
    }
}

extension ViewController: UICollectionViewDelegate {
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
       ...
    }
}

6
Я думаю, что его потенциал намного больше, чем прагмы, но в настоящее время прагмы все еще лучше, потому что расширение не показывает имена протоколов или пользовательских имен в выпадающем меню, как это делают прагмы ( см. Ответ Whasssaaahhh ниже )
nacho4d

Новый код "// MARK:" полезен, но мне также нравится ваш наглядный пример использования расширений - особенно для функций делегатов!
ElmerCat

расширения также ограничивают то, что вы можете делать - например, не сохранять свойства
Confused

1
Я использую оба, потому что extensionодно не особо выделяется в выпадающем меню элемента управления Xcode.
Николас Миари

36

Xcode 8 теперь обрабатывает это следующим образом и выглядит следующим образом в раскрывающемся списке методов:

введите описание изображения здесь


что насчет МАРКА? Это // ARK:
выглядит

Проверьте код, возможно, вы используете некоторые символы Юникода над строкой // MARK :. По какой-то причине xcode запутывается (и потому что отстой) и не может с этим справиться.
carlos_ms

3
!!!И ???синтаксис как представляется , не будет работать на Xcode 8.3.3 ...
Chris Фредерик

@ChrisFrederick Даже !!! а также ??? похоже, не работает над Xocde 11.3.1
Jayprakash Dubey

34

Этим утром в WWDC в лаборатории Swift подтвердили инженеру Apple, что в данный момент нет #pragma или его эквивалента, они считают это ошибкой, и она скоро появится, так что, я надеюсь, бета 2, я надеюсь.

Во всяком случае, это на своем пути.


Xcode теперь поддерживает ориентиры // MARK :, // TODO: и // FIXME, чтобы комментировать ваш код и перечислять их в панели переходов


6
Бета 2, его до сих пор нет
cescofry

Странный. У меня работает просто отлично. PS: обновите свой Xcode.
Даниэль

@Daniel: Какая версия XCode? Я использую Xcode 6.4 и, кажется, не работает на нем.
Джайпракаш Дубей

19

В #pragma_markSwift можно добавить три варианта :

1) // MARK: - your text here -

2) // TODO: - your text here -

3) // FIXME: - your text here -

Примечание: использует -для добавления разделителей


17

использование

// MARK: SectionName

или

// MARK: - SectionName

Это даст строку выше отметки прагмы, делая ее более читабельной.

Для удобства просто добавьте

// MARK: - <#label#>

к вашим фрагментам кода.

Альтернативный способ -

Используйте это таким образом

private typealias SectionName = ViewController
private extension SectionName  {
    // Your methods
}

Это не только добавит метку (точно так же, как метка прагмы), но и хорошо разделит код.


1
Если вы используете Swiftlint , он будет жаловаться на //MARKформат (без пробела) и предлагать // MARK: (text)( один пробел между //и MARK, без пробела между MARKи :и один пробел между :и именем раздела)
Nicolas Miari

2
@NicolasMiari, спасибо, я редактировал по вашему предложению. А также попробую использовать SwiftLint для следующего проекта. :)
Нихил Манапур

13
//# MARK: - Spinner Class Methods

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

  1. // # MARK: - Методы текста (LINE)
  2. // # MARK: текстовые методы (NO LINE)

Это работает только с комментарием MARK.

введите описание изображения здесь


12

Вы также можете быть заинтересованы в директивах компилятора Swift 4.2 / XCode 10, таких как

#warning("Some string to display")

а также

#error("Some error to display")

Это может быть полезно, когда вы действительно не хотите что-то пропустить.

введите описание изображения здесь


Круто. Я предупрежу других товарищей по команде, когда нарушит правила бойскаутов.
Саззад Хисейн Хан

9

Профессиональный программист должен использовать этот тег для хорошего кода. Это также хорошо для командной работы.

// MARK: example Web Service start here
// TODO: example 1
// FIXME: Please change BASE url before live 

Подобный метод легко найти

Подобный метод легко найти


6

В Xcode 11 они добавили миникарту, которую можно активировать Editor -> Minimap.

Миникарта покажет каждый текст пометки для быстрой ориентации в коде. Каждый знак написан как// MARK: Variables

введите описание изображения здесь


5

//MARK:не похоже , чтобы работать для меня в Xcode 6.3.2. Тем не менее, вот что я сделал, чтобы заставить его работать :

1) код:

import Cocoa

class MainWindowController: NSWindowController {

    //MARK: - My cool methods

    func fly() {
    }

    func turnInvisible() {

    }
}

2) При jump barдобавлении //MARKкомментария ничего не отображается . Однако, если я нажму на крайнее правое имя в панели переходов, в моем случае это говорит о том MainWindowController(with a leading C icon), что появится всплывающее окно с эффектом комментария // MARK: а именно заголовок, который говорит: «Мои классные методы»:

введите описание изображения здесь

3) Я также заметил, что если я нажму на один из методов в моем коде, то этот метод станет самой правой записью в панели переходов. Чтобы MainWindowController(with a leading C icon)стать самой правой записью в панели переходов, я должен щелкнуть пробел над моими методами.


Разве так не должно быть? Что вы должны нажать на верхнюю панель?
Арбитур

3

Apple , говорится в последней версии Building какао приложения ,

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

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


0

Добавить элемент списка дел: вставить комментарий с префиксом TODO :. Например: // TODO: [ваш список дел].

Добавьте напоминание об исправлении ошибки: вставьте комментарий с префиксом FIXME :. Например: // FIXME: [ваше напоминание об исправлении ошибки].

Добавить заголовок: вставить комментарий с префиксом MARK :. Например: // MARK: [заголовок вашего раздела].

Добавить разделительную линию. Чтобы добавить разделитель над аннотацией, добавьте дефис (-) перед частью комментария к аннотации. Например: // MARK: - [ваш контент]. Чтобы добавить разделитель ниже аннотации, добавьте дефис (-) после части комментария аннотации. Например: // MARK: [ваш контент] -.



0

Прагма - это способ улучшить читабельность вашего кода. Комментарии прагмы выглядят как теги на панели переходов Xcode.

//MARK:  <Your comment goes here>

Пример: в коде

//MARK: Properties

// MARK: View Life cycle

//MARK: Helper methods

Вот как это будет выглядеть в панели переходов Xcode.

введите описание изображения здесь


Вы просто должны вставить их в правильные места в вашем файле.
varunrathi28
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.