基础HTML Tag

HTML里,比较基础的Tag主要用于标题,段落和分行。

学习HTML最好的方法,就是跟着示例学。

正文标题

这个示例告诉你如何在HTML文件里定义正文标题。

HTML用<h1>到<h6>这几个Tag来定义正文标题,从大到小。每个正文标题自成一段。

<h1>This is a heading</h1>

<h2>This is a heading</h2>

<h3>This is a heading</h3>

<h4>This is a heading</h4>

<h5>This is a heading</h5>

<h6>This is a heading</h6>

段落划分

在HTML里用<p>和</p>划分段落。

<p>This is a paragraph</p>

<p>This is another paragraph</p>

换行

通过使用<br>这个Tag,可以在不新建段落的情况下换行。<br>没有Closing Tag。

用<p>换行是个坏习惯,正确的是使用<br>。

<p>This <br> is a para<br>graph with line breaks</p>

HTML注释

在HTML文件里,你可以写代码注释,解释说明你的代码,这样有助于你和他人日后能够更好地理解你的代码。

注释可以写在<!–和–>之间。浏览器是忽略注释的,你不会在HTML正文中看到你的注释。

<!– This is a comment –>

一些小建议

HTML文件会自动截去多余的空格。不管你加多少空格,都被看做一个空格。一个空行也被看做一个空格。

有些Tag能够将文本自成一段,而不需要使用<p></p>来分段。比如<h1></h1>之类的标题Tag。

更多示例

这个示例显示了段落的特性。

换行

这个示例告诉你如何在HTML文件里换行。

<html>
<body>
<p>
要<br>在一段<br>里<br>换行<br>请使用<br>br这个Tag。
</p>
</body>
</html>

 

正文标题

这个示例教会你如何在HTML文件里显示正文标题。

<html>
<body>
<h1>这是1号标题</h1>
<h2>这是2号标题</h2>
<h3>这是3号标题</h3>
<h4>这是4号标题</h4>
<h5>这是5号标题</h5>
<h6>这是6号标题</h6>
</body>
</html>

 

居中的正文标题

这个示例告诉你如何将正文标题居中显示。

<html>
<body>
<h1 align="center">这是标题</h1>
<p>上面的标题是居中显示的。</p>
</body>
</html>

 

加条横线

这个示例演示了如何在HTML文中加条横线。

<html>
<body>
<p>用hr这个Tag可以在HTML文件里加一条横线。</p>
<hr>
<p>村妇想像皇宫的生活:皇后得用金扁担挑水吧。</p>
<hr>
<p>问:谁是世界上最可怜的人?答:炮兵连炊事班战士!问:为什么?答:戴绿帽背黑锅看别人打炮。</p>
<hr>
<p>初中某数学老师讲方程式变换,在讲台上袖子一挽大声喝道:同学们注意!我要变形了!……</p>
</body>
</html>

 

代码注释

这个示例演示如何在HTML代码中加上代码注释,这些注释只显示在HTML源代码中,而源代码最终形成的网页里是看不到这些注释的。

<html>
<body>
<!--这是代码注释-->
<p>代码注释是不会显示在网页里的。</p>
</body>
</html>

 

背景颜色

这个示例演示如何改变HTML文件的背景色。

<html>
<body bgcolor="yellow">
<h2>看,这个页面是黄色的。</h2>
</body>
</html>

 

HTML基本概念

什么是HTML文件?

  • HTML的英文全称是Hypertext Marked Language,中文叫做“超文本标记语言”。
  • 和一般文本的不同的是,一个HTML文件不仅包含文本内容,还包含一些Tag,中文称“标记”。
  • 一个HTML文件的后缀名是.htm或者是.html。
  • 用文本编辑器就可以编写HTML文件。

这就试写一个HTML文件吧!

打开你的Notepad,新建一个文件,然后拷贝以下代码到这个新文件,然后将这个文件存成first.html。

<html>
<head>
<title>Title of page</title>
</head>
<body>
This is my first homepage. <b>This text is bold</b>
</body>
</html>

 

要浏览这个first.html文件,双击它。或者打开浏览器,在File菜单选择Open,然后选择这个文件就行了。

示例解释

这个文件的第一个Tag是<html>,这个Tag告诉你的浏览器这是HTML文件的头。文件的最后一个Tag是</html>,表示HTML文件到此结束。

在<head>和</head>之间的内容,是Head信息。Head信息是不显示出来的,你在浏览器里看不到。但是这并不表示这些信息没有用处。比如你可以在Head信息里加上一些关键词,有助于搜索引擎能够搜索到你的网页。

在<title>和</title>之间的内容,是这个文件的标题。你可以在浏览器最顶端的标题栏看到这个标题。

在<body>和</body>之间的信息,是正文。

在<b>和</b>之间的文字,用粗体表示。<b>顾名思义,就是bold的意思。

HTML文件看上去和一般文本类似,但是它比一般文本多了Tag,比如<html>,<b>等,通过这些Tag,可以告诉浏览器如何显示这个文件。

HTML元素(HTML Elements)

  • HTML元素(HTML Element)用来标记文本,表示文本的内容。比如body, p, title就是HTML元素。
  • HTML元素用Tag表示,Tag以<开始,以>结束。
  • Tag通常是成对出现的,比如<body></body>。起始的叫做Opening Tag,结尾的就叫做Closing Tag。
  • 目前HTML的Tag不区分大小写的。比如,<HTML>和<html>其实是相同的。

HTML元素(HTML Elements)的属性

HTML元素可以拥有属性。属性可以扩展HTML元素的能力。

比如你可以使用一个bgcolor属性,使得页面的背景色成为红色,就像这样:

<body bgcolor=”red”>

再比如,你可以使用border这个属性,将一个表格设成一个无边框的表格。如下:

<table border=”0″>

属性通常由属性名和值成对出现,就像这样:name=”value”。上面例子中的bgcolor, border就是name,red和0就是value。属性值一般用双引号标记起来。

属性通常是附加给HTML的Opening Tag,而不是Closing Tag。

HTML特殊转义字符对照表

HTML特殊转义字符对照表
字符 十进制 转义字符 字符 十进制 转义字符 字符 十进制 转义字符
? &#161; &iexcl; Á &#193; &Aacute; á &#225; &aacute;
&#162; &cent; Â &#194; &circ; â &#226 &acirc;
&#163; &pound; Ã &#195; &Atilde; ã &#227; &atilde;
¤ &#164; &curren; Ä &#196; &Auml ä &#228; &auml;
&#165; &yen; Å &#197; &ring; å &#229; &aring;
| &#166; &brvbar; Æ &#198; &AElig; æ &#230; &aelig;
§ &#167; &sect; Ç &#199; &Ccedil; ç &#231; &ccedil;
¨ &#168; &uml; È &#200; &Egrave; è &#232; &egrave;
© &#169; &copy; É &#201; &Eacute; é &#233; &eacute;
a &#170; &ordf; Ê &#202; &Ecirc; ê &#234; &ecirc;
? &#171; &laquo; Ë &#203; &Euml; ë &#235; &euml;
? &#172; &not; Ì &#204; &Igrave; ì &#236; &igrave;
/x7f &#173; &shy; Í &#205; &Iacute; í &#237; &iacute;
® &#174; &reg; Î &#206; &Icirc; î &#238; &icirc;
ˉ &#175; &macr; Ï &#207; &Iuml; ï &#239; &iuml;
° &#176; &deg; Ð &#208; &ETH; ð &#240; &ieth;
± &#177; &plusmn; Ñ &#209; &Ntilde; ñ &#241; &ntilde;
2 &#178; &sup2; Ò &#210; &Ograve; ò &#242; &ograve;
3 &#179; &sup3; Ó &#211; &Oacute; ó &#243; &oacute;
&#180; &acute; Ô &#212; &Ocirc; ô &#244; &ocirc;
μ &#181; &micro; Õ &#213; &Otilde; õ &#245; &otilde;
? &#182; &para; Ö &#214; &Ouml; ö &#246; &ouml;
· &#183; &middot; &times; &#215; &times; ÷ &#247; &divide;
? &#184; &cedil; Ø &#216; &Oslash; ø &#248; &oslash;
1 &#185; &sup1; Ù &#217; &Ugrave; ù &#249; &ugrave;
o &#186; &ordm; Ú &#218; &Uacute; ú &#250; &uacute;
? &#187; &raquo; Û &#219; &Ucirc; û &#251; &ucirc;
? &#188; &frac14; Ü &#220; &Uuml; ü &#252; &uuml;
? &#189; &frac12; Ý &#221; &Yacute; ý &#253; &yacute;
? &#190; &frac34; Þ &#222; &THORN; þ &#254; &thorn;
? &#191; &iquest; ß &#223; &szlig; ÿ &#255; &yuml;
À &#192; &Agrave; à &#224; &agrave;

HTML 30分钟入门教程

本文目标

30分钟内让你明白HTML是什么,并对它有一些基本的了解。一旦入门后,你可以从网上找到更多更详细的资料来继续学习。

什么是HTML

HTML是英文Hyper Text Mark-up Language(超文本标记语言)的缩写,它规定了自己的语法规则,用来表示比“文本”更丰富的意义,比如图片,表格,链接等。浏览器(IE,FireFox等)软件知道HTML语言的语法,可以用来查看HTML文档。目前互联网上的绝大部分网页都是使用HTML编写的。

HTML是什么样的

简单地来说,HTML的语法就是给文本加上表明文本含义的标签(Tag),让用户(人或程序)能对文本得到更好的理解。

下面是一个最简单的HTML文档:

 

<html>
<head>
<title>第一个Html文档</title>
</head>
<body>
欢迎访问<a href=”http://deerchao.net”>deerchao的个人网页</a>!
</body>
</html>

所有的HTML文档都应该有一个<html>标签,<html>标签可以包含两个部分:<head>和<body>。

<head>标签用于包含整个文档的一般信息,比如文档的标题(<title>标签用于包含标题),对整个文档的描述,文档的关键字等等。文档的具体内容就要放在<body>标签里了。

<a>标签用于表示链接,在浏览器(如IE,Firefox等)中查看HTML文档时,点击<a>标签括起来的内容时,通常会跳转到另一个页面。这个要跳转到的页面的地址由<a>标签的href属性指定。上面的<a href=”http://deerchao.net”>中,href属性的值就是http://deerchao.net。

HTML文档可以包含的内容

通过不同的标签,HTML文档可以包含不同的内容,比如文本,链接,图片,列表,表格,表单,框架等。

文本
HTML对文本的支持是最丰富的,你可以设置不同级别的标题,分段和换行,可以指定文本的语义和外观,可以说明文本是引用自其它的地方,等等等等。
链接
链接用来指出内容与另一个页面或当前页面某个地方有关。
图片
图片用于使页面更加美观,或提供更多的信息。
列表
列表用于说明一系列条目是彼此相关的。
表格
表格是按行与列将数据组织在一起的形式。也有不少人使用表格进行页面布局。
表单
表单通常由文本输入框,按钮,多选框,单选框,下拉列表等组成,使HTML页面更有交互性。
框架
框架使页面里能包含其它的页面。

HTML文档格式详细说明

前面介绍了HTML文档的基本格式,下面再做一个详细说明。

HTML文档可以用任何文本编辑器(比如记事本,UltraEdit等)创建,编辑,因为它的内容在本质也只是一些文本。

在HTML文本中,用尖括号括起来的部分称为标签。如果想在正文里使用尖括号(或者大与号小与号,总之是同一个东西),必须使用字符转义,也就是说转换字符的原有意义。<应该使用&lt;代替,>则使用&gt;,至于&符号本身,则应该使用&amp;替代(不得不说的是有很多HTML文档没有遵循这个规则,常用的浏览器也都能够分析出&到底是一个转义的开始,还是一个符号,但是这样做是不推荐的)。

标签本质上是对它所包含的内容的说明,可能会有属性,来给出更多的信息。比如<img>(图片)标签有src属性(用于指明图片的地址),width和height属性(用于说明图片的宽度和高度)。HTML里能使用哪些标签,这些标签分别可以拥有哪些属性,这些都是有规定的,知道了这里说的基本知识之后,学习HTML其实也就是学习这些标签了。本文后面会对常用的HTML标签做出简短的介绍。

标签通常有开始部分和结束部分(也被称为开始标签和结束标签),它们一起限定了这个标签所包含的内容。属性只能在开始标签中指定,属性值可以用单引号或双引号括起来。结束标签都以/加上标签名来表示。有时候,有些标签并不包含其它内容(只包括自己的属性,甚至连属性都没有),这种情况下,可以写成类似这样:<img src=”logo.gif” />。注意最后的一个空格和一个反斜杠,它说明这个标签已经结束,不需要单独的结束标签了。

某些标签包含的内容中还可以有新的标签,新的标签名甚至可能还可以与包含它的标签的名称相同(哪些标签可以包含标签,可以包含哪些标签也是有规定的)。比如:

 

<div>
<div>分类目录…</div>
<div>当前分类内容列表…</div>
</div>

在这种情况下,最后出现的标签应该最先结束。

HTML文档里所有的空白符(空格,Tab,换行,回车)会被浏览器忽略,唯一的例外是空格,对空格的处理方式是所有连续的空格被当成一个空格,不管有一个,还是两个,还是100个。之所以有这样的规则是因为忽略空白符能让使用HTML的作者以他觉得最方便的格式来排列内容,比如可以在每个标签开始后增加缩进,标签结束后减少缩进。由于英语文本中空格用得很普遍(用于分隔单词),所以对空格做了这样的特殊处理。如果要显示连续的空格(比如为了缩进),应该用&nbsp;来代表空格。

常用标签介绍

文本

最常用的标签可能是<font>了,它用于改变字体,字号,文字颜色。

 

<font size=”6″>6</font>
<font size=”4″>4</font>
<font color=”red” size=”5″>红色的5</font>
<font face=”黑体”>黑体的字</font>

加粗,下划线,斜体字也是常用的文字效果,它们分别用<b>,<u>,<i>表示:

 

<b>Bold</b>
<i>italic</i>
<u>underline</u>

还有一些标签,用来指出包含的文本有特殊的意义,比如<abbr>(表示缩写),<em>(表示强调),<strong>(表示更强地强调),<cite>(表示引用),<address>(表示地址)等等。这些标签不是为了定义显示效果而存在的,所以从浏览器里看它们可能没有任何效果,也可能不同的浏览器对这些标签的显示效果完全不同。

一篇很长的文章,如果有合适的小标题的话,就可以快速地对它的内容进行大致的了解。在HTML里,用来表示标题的标签有:<h1>,<h2>,<h3>,<h4>,<h5>,<h6>,它们分别表示一级标题,二级标题,三级标题…

 

<h1>HTML 30分钟教程</h1>
<h2>什么是HTML</h2>

<h2>HTML是什么样的</h2>

图片

<hr>标签用于在页面上添加横线。可以通过指定width和color属性来控制横线的长度和颜色。

 

<hr width=”90%” color=”red” />

<img>标签用于在页面上添加图片,src属性指定图片的地址,如果无法打开src指定的图片,浏览器通常会在页面上需要显示图片的地方显示alt属性定义的文本。

 

<img src=”http://www.w3.org/Icons/valid-xhtml10″ alt=”图片简介” />

链接

超级链接用<a>标签表示,href属性指定了链接到的地址。<a>标签可以包含文本,也可以包含图片。

 

<a href=”http://deerchao.net”>deerchao的个人网站</a>
<a href=”http://validator.w3.org”><img src=”http://www.w3.org/Icons/valid-xhtml10″ alt=”验证HTML” /></a>

分段与换行

由于HTML文档会忽略空白符,所以要想保证正常的分段换行的话,必须指出哪些文字是属于同一段落的,这就用到了标签<p>。

 

<p>这是第一段。</p>
<p>这是第二段。</p>

也有人不用<p>,而用<br>。<br>只表示换行,不表示段落的开始或结束,所以通常没有结束标签。

 

这是第一段。<br>
这是第二段。<br />
这是第三段。

有时,要把文档看作不同的部分组合起来的,比如一个典型的页面可能包括三个部分:页头,主体,页脚。<div>标签专门用于标明不同的部分:

 

<div>页头内容</div>
<div>主体内容</div>
<div>页脚内容</div>

表格

HTML文档在浏览器里通常是从左到右,从上到下地显示的,到了窗口右边就自动换行。为了实现分栏的效果,很多人使用表格(<table>)进行页面排版(虽然HTML里提供表格的本意不是为了排版)。

<table>标签里通常会包含几个<tr>标签,<tr>代表表格里的一行。<tr>标签又会包含<td>标签,每个<td>代表一个单元格。

 

<table>
<tr>
<td>2000</td><td>悉尼</td>
</tr>
<tr>
<td>2004</td><td>雅典</td>
</tr>
<tr>
<td>2008</td><td>北京</td>
</tr>
</table>

<tr>标签还可以被<table>里的<thead>或<tbody>或<tfoot>包含。它们分别代表表头,表正文,表脚。在打印网页的时候,如果表格很大,一页打印不完,<thead>和<tfoot>将在每一页出现。

<th>和<td>非常相似,也用在<tr>里边,不同的是<th>代表这个单元格是它所在的行或列的标题。

 

<table>
<thead>
<tr><th>时间</th><th>地点</th></tr>
</thead>
<tbody>
<tr><td>2000</td><td>悉尼</td></tr>
<tr><td>2004</td><td>雅典</td></tr>
<tr><td>2000</td><td>北京</td></tr>
</tbody>
</table>

列表

表格用于表示二维数据(行,列),一维数据则用列表表示。列表可以分为无序列表(<ul>),有序列表(<ol>)和定义列表(<dl>)。前两种列表更常见一些,都用<li>标签包含列表项目。

无序列表表示一系列类似的项目,它们之间没有先后顺序。

 

<ul>
<li>苹果</li>
<li>桔子</li>
<li>桃</li>
</ul>

有序列表中各个项目间的顺序是很重要的,浏览器通常会自动给它们产生编号。

 

<ol>
<li>打开冰箱门</li>
<li>把大象赶进去</li>
<li>关上冰箱门</li>
</ol>

框架

最后谈一下框架,曾经非常流行的技术,框架使一个窗口里能同时显示多个文档。主框架页里面没有<body>标签,取代它的是<frameset>。

<frameset>标签的属性Rows和Cols用于指定框架集(frameset)里有多少行(列),以及每行(列)的高度(宽度)。

<frameset>标签可以包含<frame>标签,每个<frame>标签代表一个文档(src属性指定文档的地址)。

如果觉得这样的页面还不够复杂的话,还可以在<frameset>标签里包含<frameset>标签。

 

<frameset rows=”15%,*”>
<frame src=”top.html” name=title scrolling=no>
<frameset cols=”20%,*”>
<frame src=”left.html” name=sidebar>
<frame src=”right.html” name=recipes>
</frameset>
</frameset>

30分钟以后怎么办

这篇文章只是让从没有接触过HTML的人对HTML有个初步的印象,所以很多东西都没有谈到。本文并没有列出HTML中所有的标签,对于列出的标签也没有介绍它们的全部属性。另外,没有提到的东西里还包括我觉得非常重要的CSS, JavaScript, XHTML, XML, Web Standards,以及它们与HTML的关系。不过这些也不太可能在30分钟内学会,好在只要入了门,就能利用网上很多资源继续学习。当然,如果有一本纸质书,就更好了,这方面我推荐<<HTML与XHTML权威指南>>。

2.1. 与 Objective-C API 交互

2.互用性

2.1. 与 Objective-C API 交互

互用性是让 Swift Objective-C 相接合的一种特性,使你能够在一种语言编写 的文件中使用另一种语言。当你准备开始把 Swift 融入到你的开发流程中时,你 应该懂得如何利用互用性来重新定义并提高你写 Cocoa 应用的方案。

互用性很重要的一点就是允许你在写 Swift 代码时使用 Objective-C API 接 口。当你导入一个 Objective-C 框架后,你可以使用原生的 Swift 语法实例化它 的 Class 并且与之交互。

初始化(Initialization)

为了使用 Swift 实例化 Objective-C Class,你应该使用 Swift 语法调用它的 一个初始化器。当 Objective-C init方法变化到 Swift,他们用 Swift 初始化 语法呈现。“init”前缀被截断当作一个关键字,用来表明该方法是初始化方法。那些 以“initWith”开头的 init 方法,“With”也会被去除。从“init”或者“initWith”中分离出来 的这部分方法名首字母变成小写,并且被当做是第一个参数的参数名。其余的每一 部分方法名依次变味参数名。这些方法名都在圆括号中被调用。

举个例子,你在使用 Objective-C 时会这样做: 

//Objective-C
UITableView *myTableView = [[UITableView alloc]
initWithFrame:CGRectZero style:UITableViewStyleGrouped];

 

Swift 中,你应该这样做: 

//Swift
let myTableView: UITableView = UITableView(frame: CGRectZero, style: .Grouped)

 

你不需要调用 alloc,Swift 能替你处理。注意,当使用 Swift 风格的初始化函数 的时候,“init”不会出现。

你可以在初始化时显式的声明对象的类型,也可以忽略它,Swift 能够正确判断对 象的类型。 

//Swift
let myTextField = UITextField(frame: CGRect(0.0, 0.0, 200.0, 40.0))

这里的UITableViewUITextField对象和你在 Objective-C 中使用的具有相同的功 能。你可以用一样的方式使用他们,包括访问属性或者调用各自的类中的方法。

为了统一和简易,Objective-C 的工厂方法也在 Swift 中映射为方便的初始化方 法。这种映射能够让他们使用同样简洁明了的初始化方法。例如,在 Objective-C 中你可能会像下面这样调用一个工厂方法: 

//Objective-C
UIColor *color = [UIColor colorWithRed:0.5 green:0.0 blue:0.5 alpha:1.0];

 

Swift 中,你应该这样做: 

 

//Swift
let color = UIColor(red: 0.5, green: 0.0, blue: 0.5, alpha: 1.0)

 

访问属性(Accessing Properties)
Swift 中访问和设置 Objective-C 对象的属性时,使用点语法 

///Swift
myTextField.textColor = UIColor.darkGrayColor()
myTextField.text = "Hello world"
if myTextField.editing {
myTextField.editing = false
}

get set 属性时,直接使用属性名称,不需要附加圆括号。注意, darkGrayColor 后面附加了一对圆括号,这是因为 darkGrayColor UIColor 的一个类 方法,不是一个属性。
Objective-C 中,一个有返回值的无参数方法可以被作为一个隐式的访问函 数,并且可以与访问器使用同样的方法调用。但在 Swift 中不再能够这样做了, 只有使用@property 关键字声明的属性才会被作为属性引入。

方法(Working with Methods)
Swift 中调用 Objective-C 方法时,使用点语法。

Objective-C 方法转换到 Swift 时,Objective-C selector的第一部分将会 成为方法名并出现在圆括号的前面,而第一个参数将直接在括号中出现,并且没有 参数名,而剩下的参数名与参数则一一对应的填入圆括号中。

举个例子,你在使用 Objective-C 时会这样做:

Swift 中,你应该这样做:

如果你调用一个无参方法,仍必须在方法名后面加上一对圆括号

page10image10560 page10image10984 page10image11576 page10image12160 page10image14560 page10image14984 page10image15576 page10image16160 page10image19240 page10image19832 page10image20576 page10image21168 page10image21592 page10image22016 page10image22176 page10image22600  page10image22920

//Objective-C
[myTableView insertSubview:mySubview atIndex:2];

page10image23752 page10image23912 page10image24072 page10image24496 page10image24656

//Swift

myTableView.insertSubview(mySubview, atIndex: 2)

page10image29472 page10image29896 page10image30056 page10image30480  page10image30800

//Swift
myTableView.layoutIfNeeded()

page10image31552 page10image31712 page10image31872 page10image32296

id 兼容性(idCompatibility)

Swift 包含一个叫做AnyObject的协议类型,表示任意类型的对象,就像 Objective-C 中的id一样。AnyObject协议允许你编写类型安全的 Swift 代码同时 维持无类型对象的灵活性。因为AnyObject协议保证了这种安全,Swift id 对象 导入为 AnyObject
举个例子,跟
id 一样,你可以为AnyObject类型的对象分配任何其他类型的对 象,你也同样可以为它重新分配其他类型的对象。

你也可以在调用 Objective-C 方法或者访问属性时不将它转换为具体类的类型。 这包括了 Objcive-C 中标记为 @objc 的方法。

然而,由于直到运行时才知道 AnyObject 的对象类型,所以有可能在不经意间写出 不安全代码。另外,与 Objective-C 不同的是,如果你调用方法或者访问的属性 AnyObject 对象没有声明,将会报运行时错误。比如下面的代码在运行时将会报 出一个 unrecognized selector error 错误:

但是,你可以通过 Swift optinals 特性来排除这个 Objective-C 中常见的错 误,当你用AnyObject对象调用一个 Objective-C 方法时,这次调用将会变成一次 隐式展开 optional(implicitly unwrapped optional)的行为。你可以通过 optional 特性来决定 AnyObject 类型的对象是否调用该方法,同样的,你可以把这种特性 应用在属性上。 举个例子,在下面的代码中,第一和第二行代码将不会被执行因为 length 属性和 characterAtIndex:方法不存在于 NSDate 对象中。myLength常量会被推测成可选的 

Int 类型并且被赋值为 nil。同样你可以使用 if-let 声明来有条件的展开这个方法 的返回值,从而判断对象是否能执行这个方法。就像第三行做的一样。

对于 Swift 中的强制类型转换,从 AnyObject 类型的对象转换成明确的类型并不 会保证成功,所以它会返回一个可选的值。而你需通过检查该值的类型来确认转换 是否成功。

当然,如果你能确定这个对象的类型(并且确定不是 nil),你可以添加 as 操作符 强制调用。

使用 nil(Working with nil)

Objective-C 中,对象的引用可以是值为 NULL 的原始指针(同样也是 Objective- C 中的 nil)。而在 Swift 中,所有的值包括结构体与对象的引用都被保证为非 空。作为替代,你将这个可以为空的值包装为 optional type。当你需要宣告值为空 时,你需要使用 nil。你可以在 Optionals 中了解更多。

因为 Objective-C 不会保证一个对象的值是否非空,Swift 在引入 Objective-C API 的时候,确保了所有函数的返回类型与参数类型都是 optional,在你使用 Objective-C API 之前,你应该检查并保证该值非空。 在某些情况下,你可能绝 

对确认某些 Objective-C 方法或者属性永远不应该返回一个 nil 的对象引用。为了 让对象在这种情况下更加易用,Swift 使用 implicitly unwrapped optionals 方法引 入对象, implicitly unwrapped optionals 包含 optional 类型的所有安全特性。此 外,你可以直接访问对象的值而无需检查 nil。当你访问这种类型的变量时, implicitly unwrapped optional 首先检查这个对象的值是否不存在,如果不存在, 将会抛出运行时错误。

扩展(Extensions)

Swift 的扩展和 Objective-C 的类别(Category)相似。扩展为原有的类,结构和 枚举丰富了功能,包括在 Objective-C 中定义过的。你可以为系统的框架或者你 自己的类型增加扩展,只需要导入合适的模块并且保证你在 Objective-C 中使用 的类、结构或枚举拥有相同的名字。

举个例子,你可以扩展 UIBezierPath 类来为它增加一个等边三角形,这个方法只需 提供三角形的边长与起点。

page13image5368 page13image6696

//Swift
extension UIBezierPath {
    convenience init(triangleSideLength: Float, origin: CGPoint) {
       self.init()
       let squareRoot = Float(sqrt(3))
       let altitude = (squareRoot * triangleSideLength) / 2
       moveToPoint(origin)
       addLineToPoint(CGPoint(triangleSideLength, origin.x))
       addLineToPoint(CGPoint(triangleSideLength / 2, altitude))
       closePath()

} }

你也可以使用扩展来增加属性(包括类的属性与静态属性)。然而,这些属性必须
是通过计算才能获取的,扩展不会为类,结构体,枚举存储属性。下面这个例子为

类增加了一个叫 的属性。

 

CGRect

area

//Swift
extension CGRect {
    var area: CGFloat {
    return width * height
    }
}
let rect = CGRect(x: 0.0, y: 0.0, width: 10.0, height: 50.0)
let area = rect.area
// area: CGFloat = 500.0

 

你同样可以使用扩展来为类添加协议而无需增加它的子类。如果这个协议是在 Swift 中被定义的,你可以添加 comformance 到它的结构或枚举中无论它们在 Objective-C 或在 Swift 中被定义。
你不能使用扩展来覆盖 Objective-C 类型中存在的方法与属性。 闭包(Closures)
Objective-C 中的blocks会被自动导入为 Swift 中的闭包。例如,下面是一个 Objective-C 中的 block 变量:

而它在 Swift 中的形式为

Swift 的闭包与 Objective-C 中的 blocks 能够和睦相处,所以你可以把一个 Swift 闭包传递给一个把 block 作为参数的 Objective-C 函数。Swift 闭包与函数 具有互通的类型,所以你甚至可以传递 Swift 函数的名字。

闭包与 blocks 语义上想通但是在一个地方不同:变量是可以直接改变的,而不是 像 block 那样会拷贝变量。换句话说,Swift 中变量的默认行为与 Objective-C __block 变量一致。

 

//Objective-C
void (^completionBlock)(NSData *, NSError *) = ^(NSData *data, NSError *error) {/* … */}

page14image18272 page14image18696 page14image18856 page14image19280  page14image19600

//Swift
let completionBlock: (NSData, NSError) -> Void = {data, error in /* … */}
page15image1608
比较对象(Object Comparison)
当比较两个 Swift 中的对象时,可以使用两种方式。第一种,使用(==),判断 两个对象内容是否相同。第二种,使用(===),判断常量或者变量是否为同一个对 象的实例。
Swift Objective-C 一般使用 == === 操作符来做比较。Swift == 操作 符为源自 NSObject 的对象提供了默认的实现。在实现 == 操作符时,Swift 调 用 NSObject 定义的 isEqual: 方法。

NSObject 类仅仅做了身份的比较,所以你需要在你自己的类中重新实现 isEqual: 方法。因为你可以直接传递 Swift 对象给 Objective-C API,你也应该为这些 对象实现自定义的 isEqual: 方法,如果你希望比较两个对象的内容是否相同而不 是仅仅比较他们是不是由相同的对象派生。

作为实现比较函数的一部分,确保根据 Object comparison 实现对象的 hash 属 性。更进一步的说,如果你希望你的类能够作为字典中的键,也需要遵从 Hashable 协议以及实现 hashValues 属性。

Swift 类型兼容性(Swift Type Compatibility)

当你定义了一个继承自NSObject或者其他 Objective-C 类的 Swift 类,这些类都 能与 Objective-C 无缝连接。所有的步骤都有 Swift 编译器自动完成,如果你从 未在 Objective-C 代码中导入 Swift 类,你也不需要担心类型适配问题。另外一 种情况,如果你的 Swift 类并不来源自 Objectve-C 类而且你希望能在 Objecive- C 的代码中使用它,你可以使用下面描述的 @objc 属性。

@objc 可以让你的 Swift API Objective-C 中使用。换句话说,你可以通过在任 何 Swift 方法、类、属性前添加@objc,来使得他们可以在 Objective-C 代码中使 用。如果你的类继承自 Objective-C,编译器会自动帮助你完成这一步。编译器还会 在所有的变量、方法、属性前加 @objc,如果这个类自己前面加上了@objc关键 字。当你使用@IBOutlet,@IBAction,或者是@NSManaged 属性时,@objc 也会自动加在 前面。这个关键字也可以用在 Objetive-C 中的 target-action 设计模式中,例 如,NSTimer 或者 UIButton

当你在 Objective-C 中使用 Swift API,编译器基本对语句做直接的翻译。例如, Swift API func playSong(name: String)会被解释为

*)name。然而,有一个例外:当在 Objective-C 中使用 Swift 的初始化函数,编译 器会在方法前添加“initWith”并且将原初始化函数的第一个参数首字母大写。例如, 这个 Swift 初始化函数 init (songName: String, artist: String 将被翻译为 (instancetype)initWithSongName:(NSString *)songName artist:(NSString *)artist Swift 同时也提供了一个@objc关键字的变体,通过它你可以自定义在 Objectiv-C 中转换的函数名。例如,如果你的 Swift 类的名字包含 Objecytive-C 中不支持的 字符,你就可以为 Objective-C 提供一个可供替代的名字。如果你给 Swift 函数 提供一个 Objecytive-C 名字,要记得为带参数的函数添加(:)
page16image5400

- (void)playSong:(NSString

page16image6472

page16image7032 page16image7192 page16image7776

page16image8784 page16image10272
page16image17544 page16image17968 page16image18560 page16image19728 page16image21056

//Swift
@objc(Squirrel)
class Белка {
    @objc(initWithName:)
    init (имя: String) { /*...*/ }
    @objc(hideNuts:inTree:)
    func прячьОрехи(Int, вДереве: Дерево) { /*...*/ }

}

当你在 Swift 类中使用@objc(<#name#>)关键字,这个类可以不需要命名空间即可在 Objective-C 中使用。这个关键字在你迁徙 Objecive-C 代码到 Swift 时同样也非 常有用。由于归档过的对象存贮了类的名字,你应该使用@objc(<#name#>)来声明与 旧的归档过的类相同的名字,这样旧的类才能被新的 Swift 类解档。

Objective-C 选择器(Selectors)

一个 Objective-C 选择器类型指向一个 Objective-C 的方法名。在 Swift 时代, Objective-C 的选择器被Selector结构体替代。你可以通过字符串创建一个选择 器,比如 let mySelector: Selector = “tappedButton:”。因为字符串能够自动转换为 选择器,所以你可以把字符串直接传递给接受选择器的方法。page16image35192 page16image36520 page16image37104 page16image37696 page16image38440 page16image39032

//Swift
import UIKit
class MyViewController: UIViewController {
    let myButton = UIButton(frame: CGRect(x: 0, y: 0, width: 100, height: 50))
    init(nibName nibNameOrNil: String!, bundle nibBundleOrNil: NSBundle!) {
super.init(nibName: nibName, bundle: nibBundle)
    myButton.targetForAction("tappedButton:", withSender: self)
}
func tappedButton(sender: UIButton!) {
    println("tapped button")

}

}

注意: performSelector:方法和相关的调用选择器的方法没有导入到 Swift 中因为 它们是不安全的。
如果你的 Swift 类继承自 Objective-C 的类,你的所有方法都可以用作 Objective-C 的选择器。另外,如果你的 Swift 类不是继承自 Objective-C,如果 你想要当选择器来使用你就需要在前面添加@objc 关键字,详情请看 Swift 类型兼 容性。 

 

2025 年 5 月
 1234
567891011
12131415161718
19202122232425
262728293031  

广告

分类

近期评论

标签

历史上的今天

归档