在Swift中#pragma mark?


936

在目标C中,我可以使用#pragma mark符号导航器标记代码的各个部分。由于这是C预处理程序命令,因此在Swift中不可用。在Swift中有替代方法吗?还是我必须使用丑陋的注释?


15
这对于组织我们的长代码非常重要。
iPatel 2014年

似乎注释和节标记之间不再有快速可见的区别。扩展名未命名,因此单独的文件似乎是在两种类型的注释之间进行区分的唯一方法
Stephen J


1
对于其他Swift和Xcode新手,我只会提到,每个人都在谈论的“符号导航器”是单击编辑窗口顶部“跳转栏”中最右边的东西时得到的。它不是左侧面板中的符号导航器。
RenniePet

1
@HarshilKotecha Swift是一种独立于其运行平台的编程语言。Pragma标记是Swift的一部分,可以在Linux,macOS和其他Apple平台(包括iOS)上使用。用这些平台中的任何一个标记这个问题都是荒谬的,因为实用标记是Swift本身的功能,而不是平台的功能。iOS只是Swift运行的众多平台之一。了解这一点很重要。这个问题不是关于iOS,也不是关于Linux或macOS。关于Swift。
Eric Aya

Answers:


1202

您可以使用 // MARK:


也有讨论认为,无论如何,自由使用类扩展可能是更好的做法。由于扩展可以实现协议,因此您可以(例如)将所有表视图委托方法放入扩展中,并以比#pragma mark其能力更高的语义级别对代码进行分组。


64
是的,新的开发人员协议使我们可以谈论这个问题:)
Frank Schmitt 2014年

4
您不能使用扩展来保存具有init方法的协议,例如NSCoding。如果您不能在所有情况下都使用它,则很难分开。
Matthew Knippen 2014年

149
从beta 4开始,Xcode 6可以识别// MARK:// TODO:// FIXME在Swift源代码中并将它们列出在跳转栏中。(顺便说一句,它已经在做(的OBJ)C源代码- #pragma mark是不是唯一的方式。)是的,你仍然可以添加-到您的MARK放隔板在菜单中。
rickster

17
+1用于推荐扩展程序。即使MARK现在工作,使用扩展对某些语义相关的代码(尤其是协议实现)进行分组仍然很有用。恕我直言,将协议一致性声明放在​​实现该方法的方法旁边,而不是文件顶部的5个协议声明和随机散布在下面的50个相关方法实现上,要好得多。
rickster

37
@StevenKramer:与相同#pragma mark// MARK: -只是一个分隔符,// MARK: - stuff为您提供分隔符和标题,并// MARK: - stuff -在一条注释行中为您提供分隔符,标题和另一个分隔符。
rickster

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:文本,而不仅仅是text
mostruash 2015年

在Xcode 6.1.1中对我来说效果很好,我刚刚添加了一个屏幕截图-请检查您的代码?
Ronny Webers

我忘了提到我为Objective-C文件尝试过的方法。还是要为此付出努力,谢谢。
mostruash

1
我明白了,现在很清楚了:-)最初的问题是关于Swift的,所以我没有想到。为了完整起见:在Objective-C中,您可以使用以下方法执行此操作: #pragma标记-您的标记文本在此处,或者仅#pragma标记-如果您需要一个栏,或#pragma标记您的标记文本在此处获取相同没有酒吧。(对不起,我无法正确获得代码片段的标记,我将其加粗了)
Ronny Webers

它在Xcode 8.1中进行了一些更改,但此规则通常有效,最好使用此答案:D
windsound

167

对于那些对使用扩展vs.pragma标记感兴趣的人(如第一条评论中所述),下面是如何通过Swift工程师实现它:

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
这很酷,但是如果扩展名可以包含名称,那就太好了。
Matthew Knippen 2014年

16
@Matthew-您可以使用typealias。例如typealias DataSource = SwiftTableViewController。然后extension Datasource {}
Logan

1
@PhongLe UITableViewController不是协议,它是一个类。您可能是说UITableViewControllerDataSource,但这不是示例中使用的模式。
KPM

4
我只是想知道为什么没有extension带有协议的标头(如)extension SwiftTableViewController : UITableViewController,因此更容易理解为什么将扩展名添加到类中。
Holex

7
请注意,如果您的扩展名仅作为协议实现而存在,则可以命名该扩展名:extension SwiftTableViewController : UITableViewDelegate { .. }extension SwiftTableViewController : UITableViewDatasource { .. }
Craig Otis 2014年

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

有关详细信息,请查阅此Apple文档


请注意,TODO和FIXME之后的“-”不执行任何操作。“-”仅与MARK指令相关。
rismay

1
它还在代码“ minimap”中创建了一个大写的大节标题,您可以在源文件的右侧显示该标题。很方便。
奥斯卡

65

官方文件

苹果公司有关Xcode跳转栏的官方文档:在跳转栏中添加代码注释

示例代码的跳转栏屏幕截图

样例代码

Xcode 10.1和macOS 10.14.3(Mojave)中的行为

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上不起作用
Jayprakash Dubey

56

在Objective-C代码中,Xcode检测到的注释// MARK: - foo比注释更易于移植#pragma。但是这些似乎也没有被捡起来(还?)。

编辑:在Xcode 6 beta 4中修复。


6
我肯定希望他们能尽快使它可用,因为我喜欢使所有事物都用
实用

1
我可以确认// MARK: -目前无法正常运作。
Rui Peres 2014年

无法正常工作,但是示例代码中充斥着这种注释样式,因此最终应将其提取。
Nate Cook

1
评论的可移植性重要吗?因为将Swift代码直接移植到任何其他语言已经对开发人员构成了挑战。
Holex

嗯,我看到很多人评论说它// MARK:可行,但是我使用的是Beta 6,但似乎不起作用。我试过在有无空格,有无结肠,全大写字母和混合(马克)的情况下进行尝试。有把戏吗?我需要激活偏好设置吗?
Olie 2014年

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 2015年

新的“ // MARK:”代码很有用,但是我也喜欢您使用扩展的清晰示例,尤其是对于委托函数!
ElmerCat

扩展也限制了您可以执行的操作-例如,没有存储的属性
困惑的Vorlon

1
我同时使用这两种方法,因为在extensionXcode的面包屑控件的下拉菜单中,仅凭这种方法并不能真正脱颖而出。
Nicolas Miari '17

36

Xcode 8现在按以下方式处理它,并在方法下拉列表中显示如下:

在此处输入图片说明


马克:呢?它// ARK: 在Xcode 8 中像我一样显示
fnc12 '16

检查您的代码,您可能在// MARK:行上方使用了一些Unicode字符。由于某些原因,xcode会感到困惑(并且很烂),并且无法处理。
carlos_ms

3
!!!???语法似乎并没有被工作的Xcode 8.3.3 ...
克里斯·弗雷德里克

@ChrisFrederick甚至!!! 和??? Xocde 11.3.1似乎没有工作
Jayprakash Dubey

34

今天早上在WWDC的Swift实验室中与Apple工程师确认,目前目前没有任何#pragma或同等功能,他们认为这是一个错误,并且即将发布,因此,我希望是beta 2。

无论如何,它正在路上。


Xcode现在支持// MARK :、 // TODO:和// FIXME地标来注释您的代码并在跳转栏中列出它们


6
Beta 2还没有使用
cescofry 2014年

奇怪。对我有用。PS:更新您的Xcode。
丹尼尔(Daniel)

@Daniel:哪个版本的Xcode?我正在使用Xcode 6.4,似乎无法对其进行操作。
Jayprakash Dubey

19

#pragma_mark在Swift中添加三个选项:

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:,和一个空格之间:和部分名称)
萨科Miari

2
@NicolasMiari,谢谢,我根据您的建议进行了编辑。并且还将尝试在下一个项目中使用SwiftLint。:)
Nikhil Manapure

13
//# MARK: - Spinner Class Methods

在冒号和您的描述之间添加一行以插入分隔线。这有助于组织更多代码。上面的代码和屏幕截图使用了带有一行的MARK注释。

  1. //#MARK:–文本方法(LINE)
  2. //#标记:文本方法(无行)

这仅适用于MARK注释。

在此处输入图片说明


12

您可能也对Swift 4.2 / XCode 10编译器指令感兴趣,例如

#warning("Some string to display")

#error("Some error to display")

当您真的不想错过任何东西时,它可能会很有用。

在此处输入图片说明


凉。当违反童子军规则开始时,我会警告其他队友。
Sazzad Hissain Khan,

9

专业程序员必须使用此标记才能获得良好的代码。这也有利于团队合作。

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

很容易找到这样的方法

很容易找到这样的方法


6

在Xcode 11中,他们添加了可以激活的小地图Editor -> Minimap

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)成为跳转栏中最右边的条目,我必须单击方法上方的空白。


那不是应该的样子吗?您必须单击顶部栏吗?
Arbitur

3

Apple在最新版本的Building Cocoa Apps中声明

Swift编译器不包含预处理器。相反,它利用编译时属性,构建配置和语言功能来实现相同的功能。因此,预处理器指令不会导入Swift中。

#字符似乎仍然是您使用各种构建配置和类似内容的方式,但是看起来它们正在设法减少您对大多数预处理的需求,并将其带到其他语言功能。也许这是为了帮助Playgrounds和REPL的操作尽可能接近完全编译的代码。


0

添加待办事项:插入带有前缀TODO:的注释。例如:// TODO:[您的待办事项]。

添加错误修复提醒:插入带有前缀FIXME:的注释。例如:// FIXME:[您的错误修复提醒]。

添加标题:插入带有前缀MARK:的注释。例如://标记:[您的部分标题]。

添加分隔线:要在注释上方添加分隔符,请在注释的注释部分之前添加连字符(-)。例如://标记:-[您的内容]。要在注释下方添加分隔符,请在注释的注释部分之后添加连字符(-)。例如://标记:[您的内容]-。



0

实用标记是提高代码可读性的一种方法。杂注注释会像Xcode跳转栏上的标签一样出现。

//MARK:  <Your comment goes here>

示例:在代码中,

//MARK: Properties

// MARK: View Life cycle

//MARK: Helper methods

这就是它出现在Xcode跳转栏中的方式。

在此处输入图片说明


您只需要将它们插入文件中的正确位置即可。
varunrathi19年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.