在目标C中,我可以使用#pragma mark在符号导航器中标记代码的部分。因为这是一个C预处理器命令,所以它在swift中不可用。有没有一个立场在这迅速,还是我必须使用丑陋的评论?
- 这对于组织我们的长代码非常重要。
- 注释和节标记之间似乎不再存在快速可见的差异。扩展名没有命名,因此单独的文件似乎是在这两种类型的注释之间进行划分的唯一方法。
- 您可以查看这个:stackoverflow.com/a/33040068/1753005
- 对于其他Swift和Xcode新手,我只会提到,当你点击编辑窗口顶部的"跳转条"中最右边的东西时,每个人都在谈论的"符号导航器"。它不是左面板中的符号导航器。
- @Harshil Kotecha"ios"不是这个问题的好关键词。Swift可以在iOS、MacOS、TVO、WatchOS甚至Linux上工作。像这类关于swift的问题根本不是关于iOS的具体问题。
- @Moritz Hahah很多次的标签都被更改和删除了,只是为了再次添加才能删除??
- @Moritz iOS是大多数谷歌搜索关键词,即使是tvos开发者也会像iOS中的"param mark"一样搜索?这个问题要求大多数新开发人员学习swift。所以我认为iOS和swift都是这个问题的好关键词。
- @HarshilkotechaSwift是一种独立于运行平台的编程语言。pragma mark是swift的一部分,可用于Linux、MacOS和其他苹果平台,包括iOS。用这些平台来标记这个问题是荒谬的,因为pragma mark是swift本身的特性,而不是平台的特性。iOS只是Swift运行的众多平台之一。理解这一点很重要。这个问题与iOS无关,也与Linux或MacOS无关。是关于斯威夫特的。
- 我最初的标签是iOS和Swift,我添加了iOS,因为这是我通常搜索的标签,并且总是得到很多回复,而且那时Swift不是开源的,没有打开它的讨论。
您可以使用// MARK:。
也有人讨论过自由使用类扩展可能是更好的实践。因为扩展可以实现协议,所以您可以将所有表视图委托方法放在一个扩展中,并将代码分组到比#pragma mark所能实现的语义级别更高的级别。
- 是的,新的开发者协议让我们来谈谈这些东西:)
- 不能使用扩展来保存具有init方法的协议,例如nscoding。如果不能在所有情况下都使用它,就很难将其分开。
- 自由使用类扩展会损害性能吗?
- 在beta 4中,xcode 6在swift源中识别// MARK:、// TODO:和// FIXME,并将它们列在跳转栏中。(顺便说一句,它已经在(obj)c source中做过了——#pragma mark不是唯一的方法。)是的,您仍然可以将-添加到您的MARK中,以便在菜单中放置分隔符。
- +1.建议延期。即使MARK现在工作,使用扩展对一些语义相关的代码(尤其是协议实现)进行分组仍然是有用的。imho如果您的协议一致性声明正好位于实现它的方法旁边,那么它的阅读效果会更好,而不是文件顶部的5个协议声明和下面随机分布的50个相关方法实现。
- @matddipasquale-无性能影响
- 我真的很喜欢使用类扩展的建议,但这绝不是一个"更好的实践",因为pragma mark(现在是//mark:)是一个更通用的功能,并在xcode的选择器下拉框中以粗体显示。
- @Rickster你怎么把分隔符放在一个//标记中?我似乎找不到它的语法。
- @Stevenkramer:和#pragma mark一样。// MARK: -只是一个分隔符,// MARK: - stuff给你一个分隔符和一个头,// MARK: - stuff -给你一个分隔符、一个头和另一个分隔符,都在一个注释行中。
- 好的,谢谢,那时分隔符必须是快速的。
- fwiw,苹果关于添加与扩展协议一致性的文档:developer.apple.com/library/ios/documentation/swift/conceptu‌&8203;al/…
- 这就是我喜欢添加到代码片段中的内容。添加一个名为"pragma mark"的代码段,其中包含快捷方式"mark"和内容//mark:。然后,只需输入"mark"并输入弹出建议,我想您会喜欢结果的。
- "新的开发人员协议让我们可以谈论这些东西"--这几乎就像你建造核武器,而不是软件
- 此功能是从xcode 7.2开始实现的。
- 型作为旁注,在Xcode7.3中,必须在它们自己的行中使用标记。例如(至少对于objective-c),如果你写[someObject someMethod]; // MARK: Some marking text,标记将被忽略,但是如果你在空行中写// MARK: Some marking text,它将工作正常。
- 型谢谢你的解释。
对于那些对使用扩展和pragma标记感兴趣的人(如第一条注释中所述),下面是如何从swift工程师那里实现它:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| 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
}
} |
这也不一定是最佳实践,但如果你愿意的话,这就是你如何做到的。
- 型这很酷,但是如果扩展名可以有名称就更好了。
- 型另一个问题是它不能适用于所有协议,比如nscoding。init方法不能进入扩展。
- 型@马修-你可以用typealias。例如typealias DataSource = SwiftTableViewController。然后是extension Datasource {}。
- 型将协议添加到扩展会更干净吗?像这样
- 型@PhongleUITableViewController不是一个协议,它是一个类。您可能是指UITableViewControllerDataSource,但这不是示例中使用的模式。
- 型@KPM对不起你的权利,认为它是一个视图控制器与一个UITableView添加。
- 型我只是想知道为什么extension没有得到带有协议的头文件,比如extension SwiftTableViewController : UITableViewController,看看你为什么把扩展添加到类中会更容易阅读。
- 型但它仍然不会出现在方法导航菜单中,比如用于分隔菜单项的pragma mark。
- 型@goodsp33d我假设这样做的好处是,您可以有单独的文件来组织代码,然后在这些文件中声明扩展名。所以我可能有MyViewControllerDatasource.swift,并且在里面有一个与数据源相关的扩展……至少这是我组织代码的方式。
- 型@Literphor不知道这一点:)这对组织代码真的很有帮助。我记得有些单例类的代码行高达2千行。
- 型如果基础是uiviewcontroller,我喜欢它。否则我们已经结婚了。但实际上,它只是语义,而且它确实使删除"分组"代码比使用pragma更明显!
- 型嗨,只是好奇,这位工程师是谁,你从哪里读到的?谢谢。
- 型为什么这不是最佳实践?自由使用类扩展是否会损害性能?
- 型@在WWDC14期间,我在斯威夫特实验室问过这个问题——不记得工程师的名字了。
- 型@matddipasquale只是说,我不知道这是否是最佳实践,因为有其他方法可以实现这一点,例如创建数据源对象(nsObject的子类),并将其设置为TableView的数据源。没有听说任何关于类扩展会损害性能的消息。
- 型请注意,如果您的扩展仅作为协议实现而存在,那么您可以将扩展命名为:extension SwiftTableViewController : UITableViewDelegate { .. }和extension SwiftTableViewController : UITableViewDatasource { .. }。
- 型我喜欢使用类扩展(对代码进行分组的一种好方法)和//mark:style,以便在下拉列表中进行区分。
- 型所以如果你要做很多标记,那么你能做很多这样的扩展吗?
- 型我写了一篇关于如何在swift中使用扩展名的详细博客文章:natashatherobot.com/using-swift-extensions
- 型NumberOfSectionsTableView不需要声明,因为默认值已经是1。
在xcode 5之前,存在预处理器指令#pragma mark。
从Xcode6开始,您必须使用// MARK:。
这些预处理器特性允许将一些结构带到源代码编辑器的函数下拉框中。
一些例子:
->前面是一个水平分隔符
1
| // MARK: your text goes here |
->在下拉列表中用粗体显示"此处显示您的文本"
1
| // MARK: - your text goes here |
->在下拉列表中以粗体显示"此处显示您的文本",前面是水平分隔符
更新:添加了屏幕截图,因为有些人似乎仍然对此有问题:
- Xcode6.1.1中没有使用// MARK: - textfor me的分隔符,下拉列表显示mark:text而不是text。
- 在Xcode6.1.1中我可以正常工作,我刚添加了一个屏幕截图-请检查您的代码?
- 我忘了提我试着把它作为客观C文件。投票支持这项努力,谢谢。
- 我明白了,现在很清楚了:(-)最初的问题是关于斯威夫特的,所以我没想到。为了完整性:在Objective-C中,您可以使用以下方法来完成相同的操作:pragma mark-您的标记文本放在这里,或者只是pragma mark-如果您需要一个条形图,或者pragma mark-您的标记文本放在这里以获得相同的无条形图。(很抱歉,我无法为代码片段获得正确的标记,我已将其加粗)
- 在Xcode8.1中它有点变化,但是这个规则通常是有效的,最好选择这个答案:d
在Objective-C中使用Pragma mark - [SOME TEXT HERE]对多个功能进行了分行分组。
在Swift中,您可以使用MARK, TODO OR FIXME来实现这一点。
一、标记://MARK: viewDidLoad。
这将创建一条水平线,函数分组在viewdidload下(如屏幕截图1所示)。
二。TODO://TODO: - viewDidLoad。
这将在todo:-viewdidload类别下对函数进行分组(如屏幕截图2所示)
三、固定件://FIXME - viewDidLoad。
这将在fixme下对函数进行分组:-viewdidload类别(如屏幕截图3所示)
- 谢谢,这适用于Xcode 7和Swift 2.0
- 注意,todo和fixme后面的"-"没有做任何事情。"-"仅与标记指令相关。
在objective-c代码中,xcode检测像// MARK: - foo这样的注释,这比#pragma更易于移植。但这些似乎也没有被收集起来(还没有?).
编辑:在Xcode6测试版4中修复。
- 我当然希望他们能尽快提供,因为我喜欢用pragma marks>来组织一切。<
- 我可以确认,// MARK: -暂时不工作。
- @是的,我也试过了:(
- 不起作用,但是示例代码中充满了这种风格的注释,因此最终应该提取它。
- 它在苹果的示例列表应用程序中工作。
- 评论是否应该是可移植的?因为直接将一个swift代码移植到任何其他语言对开发人员来说已经是一个挑战。
- 嗯,我看到很多人都在评论它的有效性,但我在测试版6上,而// MARK:似乎不起作用。我尝试过没有空格、有冒号和没有冒号、全大写和混合(标记)。有什么把戏吗?我需要激活一个pref还是什么?
- @奥利你忘了冲刺。
- @尼古拉:在我的代码中,我有破折号,尽管我觉得不需要破折号。从pragma,破折号只是将分隔符添加到菜单中。我觉得这里的钥匙是MARK:,类似于FIXME:或TODO:。
- @奥利,你是对的,当然。不过,我在Xcode中看到了分隔符和标题。
- 正确的。其他人都看到了。这就是为什么我问是否有一些奇怪的配置,设置,拼写或其他东西,使它不显示。不能在评论中附加图片,但我对iOS、xcode等非常流利,我不认为这是"愚蠢的用户错误"。找到你愚蠢的用户错误的关键是在一个公开的论坛上发布你确信不是的!;)
官方文件
苹果关于xcode跳转条的官方文件:添加代码注释到跳转条
示例代码的跳转条截图
Xcode 10.1和MacOS 10.14.3中的行为(mojave)
Xcode 10.0和MacOS 10.13.4(High Sierra)中的行为
Xcode 9.4.1和MacOS 10.13.0中的行为
讨论
!!!:和???:有时无法显示。
Xcode8现在按如下方式处理它,并在方法下拉列表中显示如下:
- 马克呢?在xcode 8中,它显示出像// ARK: 一样的东西。
- 检查代码,您可能在//mark:line上面使用了一些Unicode字符。出于某种原因,Xcode会感到困惑(而且很糟糕),无法处理。
- !!!和???语法似乎不适用于xcode 8.3.3…
我认为用Extensions代替#pragma mark是更好的方法。
使用Extensions前的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| 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后的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| 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) {
...
}
} |
- 型我认为它的潜力远远超过了pragma,但此时pragma仍然更好,因为扩展不会像pragma那样在下拉菜单中显示协议名或自定义名称(请参见下面的whasssaahh的答案)。
- 新的"//mark:"代码很有用,但我也喜欢您关于如何使用扩展的清晰示例-尤其是对于委托函数!
- 扩展还限制了您可以做的事情-例如,没有存储的属性
- 我两者都使用,因为只有extension在xcode的breadcrumb控件的下拉菜单中并不突出。
今天早上在WWDC的Swift实验室与一位苹果工程师确认,目前还没有任何杂注或等效物,他们认为这是一个bug,很快就会出现,所以我想应该是beta 2。
不管怎样,一切都在进行中。
Xcode现在支持//mark:,//todo:和//fixme标志来注释代码和在跳转栏中列出它们
- 型贝塔2,还没有
- 型在Xcode Beta 3中?
- 型贝塔4现在有了。
- 型这三条评论在Xcode 6.3.2中都不起作用。
- 型很奇怪。对我来说很好。PS:更新你的xcode。
- 型@丹尼尔:Xcode的哪个版本?我使用的是Xcode6.4,但似乎没有在使用它。
在swift中增加#pragma_mark有三种选择:
1)江户十一〔1〕号
2)江户十一〔2〕
3)江户十一〔3〕。
注:添加分隔符时使用-。
使用
或
这将在pragma mark上面给出一行,使其更具可读性。
为方便起见,只需添加
到您的代码段。
替代方式-
用这种方法
1 2 3 4
| private typealias SectionName = ViewController
private extension SectionName {
// Your methods
} |
这不仅可以添加标记(就像pragma标记一样),而且可以很好地隔离代码。
- 如果使用swiftlint,会抱怨//MARK格式(无空格),建议// MARK: (text)(//和mark之间有一个空格,MARK和:之间没有空格,:和段名之间有一个空格)
- @尼古拉斯米亚里,谢谢,我已经根据你的建议进行了编辑。也将尝试在下一个项目中使用swiftlint。:)
1
| //# MARK: - Spinner Class Methods |
在冒号和说明之间添加一行以插入分隔符行。这有助于更好地组织代码。上面的代码和屏幕截图使用了包含行的标记注释。
//#标记:–文本方法(行)
//#标记:文本方法(无行)
这只适用于标记注释。
专业编程人员必须使用这个标签来获得良好的代码。这也有利于团队合作。
1 2 3
| // MARK: example Web Service start here
// TODO: example 1
// FIXME: Please change BASE url before live |
很容易找到这样的方法
您也可能对swift 4.2/xcode 10编译器指令感兴趣,例如
1
| #warning("Some string to display") |
和
1
| #error("Some error to display") |
当你真的不想错过什么东西的时候,它可能会很有用。
在Xcode6.3.2中,//MARK:似乎不适合我。但是,这是我为使它工作所做的:
1)代码:
1 2 3 4 5 6 7 8 9 10 11 12 13
| import Cocoa
class MainWindowController: NSWindowController {
//MARK: - My cool methods
func fly() {
}
func turnInvisible() {
}
} |
2)在jump bar中,添加//MARK时,没有任何变化:注释。但是,如果我单击跳转栏中最右边的名称,在我的例子中它显示为MainWindowController(with a leading C icon),那么将显示一个弹出窗口,显示//mark:comment的效果,即显示"我的酷方法"的标题:
3)我还注意到,如果我单击代码中的某个方法,那么该方法将成为跳转栏中最右边的条目。为了让MainWindowController(with a leading C icon)成为跳转条中最右边的条目,我必须单击方法上方的空白。
苹果在最新版本的Cocoa应用程序中声明,
The Swift compiler does not include a preprocessor. Instead, it takes
advantage of compile-time attributes, build configurations, and
language features to accomplish the same functionality. For this
reason, preprocessor directives are not imported in Swift.
角色似乎仍然是您处理各种构建配置和类似的事情的方式,但看起来他们试图减少您对大多数预处理的需求,以语用的方式,并将您完全转发到其他语言功能。也许这是为了帮助操场的运作和repl尽可能接近完全编译的代码。
Add a to-do item: Insert a comment with the prefix TODO:. For
example: // TODO: [your to-do item].
Add a bug fix reminder: Insert a comment with the prefix FIXME:. For
example: // FIXME: [your bug fix reminder].
Add a heading: Insert a comment with the prefix MARK:. For example:
// MARK: [your section heading].
Add a separator line: To add a separator above an annotation, add a
hyphen (-) before the comment portion of the annotation. For example:
// MARK: - [your content]. To add a separator below an annotation, add
a hyphen (-) after the comment portion of the annotation. For
example: // MARK: [your content] -.
试试这个:
//标记:重新加载TableView
func reloadTableView()。{
}