Swift快速入门(五)集合
最后更新于:2022-04-01 09:51:02
相关文章
[Swift快速入门(一)第一个Swift程序](http://blog.csdn.net/itachi85/article/details/50531727)
[Swift快速入门(二)基本数据类型](http://blog.csdn.net/itachi85/article/details/50596987)
[Swift快速入门(三)运算符](http://blog.csdn.net/itachi85/article/details/50638125)
[Swift快速入门(四)流程控制](http://blog.csdn.net/itachi85/article/details/50658955)
### 前言
Swift提供了数组和字典两种集合类型来存储数据,Swift的数组用来存储顺序相同类型相同的类型,字典则采用kay-value的形式存储数据。
**1.数组**
数组用来存储同一个数据类型的多个数据,通常可通过数组元素的索引来访问数组元素。
####声明数组
声明数组有两种语法:
1. 使用泛型语法。格式为:Array
2. 使用简化语法。格式为:[类型]
~~~
// 使用泛型语法声明数组
var arr : Array<String>
// 使用简化语法声明数组
var names : [String]
~~~
####创建数组
创建数组也有两种方式:
1\. 使用Array的构造器创建数组
2\. 使用简化语法创建数组
~~~
// 创建一个空数组,并将该空数组赋值给myArr变量
arr= Array<String>()
// 创建一个包含10个"moon"元素的数组,并将该数组赋值给names变量
names = Array<String>(count: 10, repeatedValue: "moon")
// 使用简化语法创建数组,并将数组赋值给values变量
var values = ["2" , "3" , "3" , "4" , "5" , "6"]
~~~
####遍历数组
普通的循环遍历数组:
~~~
for var i = 0; i < values .count ; i++
{
print(values[i])
}
~~~
for-in循环遍历数组:
~~~
for value in values{
//会报错"canot assign to value:'value' is a 'let'...
//value="5"
print(value)
}
~~~
需要注意的是,在使用for-in循环遍历是,不允许对循环常量进行赋值,因为for-in循环隐式的用let来声明了该常量。
####修改数组
Array提供了append()方法来添加元素:
~~~
// 使用var定义一个可变数组
var languages = ["Swift"]
// 添加元素,输出为["Swift","Java"]
languages.append("Java")
~~~
还可以用”+“来进行数组的的加法运算:
~~~
//输出为["Swift","Java","Ruby"]
languages=languages+["Ruby"]
~~~
Array提供了insert()方法来添加元素:
~~~
// 插入元素,这时数组第一个元素为"Go"
languages.insert("Go" , atIndex:0)
~~~
Array支持在”[]”中使用Range,这样可以一次性获取和赋值多个数组元素:
~~~
var languages = ["Swift", "OC", "PHP", "Perl" , "Ruby" , "Go"]
// 获取languages中数组中索引为1~4的元素
let subRange = languages[1..<4]
print(subRange) // 输出[OC, PHP, Perl]
// 将languages中数组中索引为2~4的元素替换成"C/C++" , "Python"
languages[2...4] = ["C/C++" , "Python"]
print(languages) // 输出[Swift, OC, C/C++, Python, Go]
// 清空数组
languages[0..<languages.count] = []
print(languages) // 输出[]
~~~
Array提供了removeAtIndex()、removeLast()和removeAll()方法来进行删除:
~~~
var languages = ["Swift", "OC", "PHP", "Perl" , "Ruby" , "Go"]
// 删除索引为2的元素,删除"PHP"
languages.removeAtIndex(2)
print(languages) // 输出[Swift,Perl,OC, Ruby, Go]
// 删除最后一个元素,删除"Go"
languages.removeLast()
print(languages) // 输出[Swift, Perl,OC, Ruby]
// 删除所有元素
languages.removeAll()
print(languages) // 输出[]
print(languages.count) // 输出0
~~~
**2.字典**
字典用于保存具有映射关系的数据,key和value都可以是任何数据类型的的数据,其中字典的key不允许重复。
####声明字典
声明字典有两种语法:
1\. 使用泛型语法,格式为:Dictionary
~~~
// 使用泛型语法声明字典
var dict : Dictionary<String, String>
// 使用简化语法声明字典
var scores : [String:Int]
~~~
####创建字典
同样的创建字典也有两种方式:
1. 使用Dictionary的构造器
2. 使用简化语法
~~~
// 创建一个Dictionary结构体,使用默认的参数
dict = Dictionary<String, String>()
// minimumCapacity至少包含键值对的个数,默认值为2
scores = Dictionary<String, Int>(minimumCapacity:5)
// 使用简化语法创建字典
var health = ["身高":"178" , "体重":"75"]
~~~
####使用字典
访问字典的value需要在字典变量后紧跟一个方括号”[]”就可以了,方括号里是字典value对应的key值。
~~~
//将key值赋值给height
var height = health["身高"]
print(height) // 输出Optional("178")
// 访问并不存在的key对应的value时,将会返回nil
var energy = health["能量"]
print(energy) // 输出nil
~~~
从上面的代码可以看出,根据key值访问字典对应的value时,返回的是包含value值的可选类型,因为字典不确定是否这个键值对存在,当键值对存在时则返回key对应的value,否则就返回nil。这时我们可以通过强制解析来解决这个问题:
~~~
//height的类型是String?,而不是String
var height : String? = health["身高"]
if height != nil
{
// 使用!执行强制解析,输出为178
print(height!)
}
~~~
for-in循环同样可以用来遍历字典:
~~~
for heal in health
{
print(heal) //输出 ("身高",178) ("体重",75)
}
~~~
####字典的key集和value集
如果程序只需要访问字典的key集和value集,只需要访问字典的keys属性或者values属性。
~~~
var healths = ["身高":"178" , "体重":"75"]
var keys=Array(healths.keys)
var values=Array(healths.values)
print(keys) //输出["身高","体重"]
print(values)//输出["178","75"]
~~~
####修改字典
字典提供了updataValue()方法来修改字典的value值,该方法会返回一个Sting?类型的值,如果key值存在则修改成功,如果key值不存在则返回nil,但会新增一个key-value值
~~~
var healths = ["身高":"178" , "体重":"75"]
var result=healths.updateValue("68",forKey:"体重")
print(result) // 输出Optional("75")
print(health) // 输出["身高":"178" , "体重":"68"]
var result=healths.updateValue("A",forKey:"血型")
print(health) // 输出["血型":"A","身高":"178" , "体重":"68"]
~~~
字典还提供了如下的方法来删除元素:
1. removeValueForKey:删除指定key对应的value
2. removeAll:清空字典
~~~
var languages = ["Swift":9000, "OC":8600, "PHP":3400,
"Perl":4300 , "Ruby":5600 , "Go": 5600]
// 删除key为"PHP"的key-value对
languages.removeValueForKey("PHP")
// 删除key为"Perl"的key-value对
languages.removeValueForKey("Perl")
// 下面输出:[Go: 5600, OC: 8600, Ruby: 5600, Swift: 9000]
print(languages)
print(languages.count) // 输出4
~~~
还可以将Key对应的Value值赋值为nil来删除该key-value对:
~~~
// 删除key为"Go"的key-value对
languages["Go"] = nil
print(languages) // 输出[OC: 8600, Ruby: 5600, Swift: 9000]
// 删除所有元素
languages.removeAll()
print(languages) // 输出[:]
print(languages.count) // 输出0
~~~
Swift快速入门(四)流程控制
最后更新于:2022-04-01 09:50:59
相关文章
[Swift快速入门(一)第一个Swift程序](http://blog.csdn.net/itachi85/article/details/50531727)
[Swift快速入门(二)基本数据类型](http://blog.csdn.net/itachi85/article/details/50596987)
[Swift快速入门(三)运算符](http://blog.csdn.net/itachi85/article/details/50638125)
**1.分支结构**
Swift提供两种常见的分支控制结构:if语句和swich语句。一般来说,当条件简单且可能情况较少时使用if语句;当条件比较复杂情况较多时则可以考虑使用swich语句。
####if条件语句
if语句有三种形式
**第一种:**
~~~
if expression
{
statements...
}
~~~
**第二种:**
~~~
if expression
{
statements...
}
else
{
statements...
}
~~~
**第三种**
~~~
if expression
{
statements...
}
else if expression
{
statements...
}
else
{
statements...
}
~~~
简单举个例子:
~~~
var age = 30
if age > 20
{
print("年龄大于20岁")
}else
{
print("年龄小于等于20岁")
}
~~~
####switch分支语句
switch语法的语句格式为:
~~~
switch expression
{
case value1:
statements...
case value2 ,value3:
statements...
default:
statements...
}
~~~
举个简单例子:
~~~
var score = 78
switch score
{
case 91...100:
print("优秀")
case 81...90:
print("良好")
case 71...80:
print("中")
case 60...70:
print("及格")
case 0..<60:
print("不及格")
default:
break
}
~~~
使用switch语句需要注意的是,Swift的任意一个case块执行完成后会自动终止该switch语句,因此要求每个case块至少要包含一条语句,否则会导致编译错误。
**2.循环结构**
循环语句可能包括如下4个部分:
* 初始化语句(init_statements):在循环开始之前完成一些初始化操作。
* 循环条件(test_expression):决定是否执行循环体。
* 循环体(body_statements):循环的主体。
* 迭代语句(iteration_statements):通常用于控制循环条件的变量,使得循环在合适的时候结束。
####while循环语句
while循环语句的语法格式:
~~~
[init_statements]
while test_expression
{
statements
[iteration_statements]
}
~~~
举个简单例子:
~~~
// 循环的初始化条件
var count = 0
while count < 10
{
print("count:\(count)")
// 迭代语句
count++
}
~~~
####do while循环语句
do while循环先执行循环体,然后才判断循环条件,如果循环条件为真,则执行下一次循环,否则中止循环。do while循环的语法格式如下:
~~~
[init_statements]
do
{
statements
[iteration_statements]
}while test_expression
~~~
举个简单例子:
~~~
// 循环的初始化条件
var count = 1
do
{
print("count: \(count)")
// 循环迭代语句
count++
} while count < 10
~~~
####for 循环语句
for 循环的基本语法格式如下:
~~~
for [init_statements]; [test_expression]; [iteration_statements]
{
statements
}
~~~
举个简单例子:
~~~
for var count = 0 ; count < 10 ; count++
{
print("count: \(count)")
}
~~~
####for-in 循环语句
for-in循环专门用于遍历范围、序列和集合等包含的元素。for-in循环的基本语法格式如下:
~~~
for 常量名 in 范围|集合
{
statements
}
~~~
下面程序使用for-in循环遍历范围:
~~~
for number in 1..3
{
print(number)
}
~~~
**3.控制循环**
Swift提供了break和continue来控制循环;另外return也可以通过结束整个方法来结束循环。
####用break结束循环
~~~
for var i = 0; i < 10 ; i++
{
print("i的值是:\(i)")
if i == 3
{
// 执行该语句时将结束循环
break
}
}
~~~
####用continue忽略本次循环剩余语句
~~~
for var i = 0; i < 3 ; i++
{
print("i的值是\(i)")
if i == 1
{
// 忽略本次循环的剩下语句
continue
}
print("continue后的输出语句")
}
~~~
**输出的结果为:**
i的值是0
continue后的输出语句
i的值是1
i的值是2
continue后的输出语句
从运行结果来看,当i等于1时,程序没有输出“continue后的输出语句”,因为程序执行到continue时,忽略了本次循环中continue语句后的代码。
####用return结束方法
~~~
func test()
{
for var i = 0; i < 10 ; i++
{
print("i的值是:\(i)");
if i == 1
{
return;
}
print("return后的输出语句")
}
}
test()
~~~
上面的程序,当i等于1时程序将完全结束。虽然return不是用来专门控制循环语句的关键字,但通过return语句确实可以结束一个循环。
Swift快速入门(三)运算符
最后更新于:2022-04-01 09:50:57
相关文章
[Swift快速入门(一)第一个Swift程序](http://blog.csdn.net/itachi85/article/details/50531727)
[Swift快速入门(二)基本数据类型](http://blog.csdn.net/itachi85/article/details/50596987)
**1.赋值运算符**
赋值运算(a = b),表示用b的值来初始化或更新a的值:
~~~
var b = 10
var a = 5
a = b // a 现在等于 10
~~~
Swift 的赋值语句没有返回值,所以以下代码是错误的:
~~~
// 此句错误, 因为 x = y 并不返回任何值
if x = y {
}
~~~
**2.算术运算符**
Swift 让所有数值类型都支持了基本的四则运算:
加法(+)
减法(-)
乘法(*)
除法(/)
~~~
var a=1 + 2 // 等于 3
var b=5 - 3 // 等于 2
var c=2 * 3 // 等于 6
var d=10.0 / 2.5 // 等于 4.0
~~~
**3.溢出运算符**
Swift不允许整型变量或者常量被赋值一个超出其表数范围的数值,如果试图这么干,则会出现运行时错误:
~~~
var a:Int16=32767
//a+1的值超出了Int16的表数范围,则下面的代码会导致错误
a=a+1
~~~
如果希望数据溢出时Swift程序只是对一出的数据位进行截断而不是导致错误,则可以使用以&开头的溢出运算符:
* 溢出加法 &+
* 溢出减法 &-
* 溢出乘法 &*
* 溢出除法 &/
* 溢出求余 &%
####值的上溢
下面例子使用了溢出加法&+来处理无符号整数的上溢出:
~~~
// max等于UInt8的最大整数 255
var max = UInt8.max
// 这时候 max 等于 0
max= max&+ 1
~~~
max用Int8所能承载的最大值255(二进制11111111),然后用&+加1。然后UInt8就无法表达这个新值的二进制了,也就导致了这个新值上溢出了,大家可以看下图。溢出后,新值在UInt8的承载范围内的那部分是00000000,也就是0。
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-09_56dfc829ad36f.jpg)
####值的下溢
数值也有可能因为太小而越界:
~~~
// min等于UInt8的最小值0
var min= UInt8.min
// 此时 min等于 255
min= min&- 1
~~~
UInt8的最小值是0(二进制为00000000)。使用&-进行溢出减1,就会得到二进制的11111111即十进制的255。
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-09_56dfc829bf300.jpg)
####除零溢出
整数和整数在进行除法或者求余运算时,如果被除数为0,程序将会出错:
~~~
let x=10
let y = x / 0 //出错
~~~
改为可溢出运算符:
~~~
let x=10
let y = x &/ 0 //结果为0
~~~
**4.位运算符**
假设变量A=60,变量B=13,那么位运算的结果如下:
~~~
A = 0011 1100
B = 0000 1101
A & B = 0000 1100 //结果为12
A|B = 0011 1101 //结果为61
A^B = 0011 0001 //结果为49
~A = 1100 0011 //结果为-61
~~~
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-09_56dfc829d4020.jpg)
**5.范围运算符**
Swift包括两个范围的运算符,用于表达值的范围。
####闭范围运算符
闭范围运算符a…b定义一个包含从a到b(包括a和b)的所有值的范围,其中a不能大于b。 闭范围运算符在迭代一个范围的所有值时是非常有用的,如在for-in循环中:
~~~
//结果为1到5
for num in 1...5 {
print(num)
}
~~~
####半开范围运算符
半开范围运算符`a..<b`用于定义一个从a到b(包括a边界不包括b边界),其中a不能大于b。
~~~
//结果为1到4
for num in 1..<5 {
print(num)
}
~~~
**6.比较运算符**
* 等于(a == b)
* 不等于(a!= b)
* 大于(a > b)
* 小于(a < b)
* 大于等于(a >= b)
* 小于等于(a <= b)
每个比较运算都返回了一个标识表达式是否成立的布尔值:
~~~
1 == 1 // true
2 != 1 // true
2 > 1 // true
1 < 2 // true
1 >= 1 // true
2 <= 1 // false
~~~
**7.逻辑运算符**
逻辑运算的操作对象是逻辑布尔值。Swift 支持基于 C 语言的三个标准逻辑运算。
* 逻辑非运算(!a)对一个布尔值取反,使得true变false,false变true。
* 逻辑与(a && b)表达了只有a和b的值都为true时,整个表达式的值才会是true。
* 逻辑或(a || b)它表示了两个逻辑表达式的其中一个为true,整个表达式就为true。
**8.三目运算符**
三目运算符的格式为:
~~~
expression? if-true-statement: if-false-statement
~~~
如果逻辑表达式expression为真则执行并返回第二个操作数的值; 如果不为真则执行并返回第三个操作数的值。
~~~
var a = 5
var b = 3
var str = a > b ? "a大于b" : "a不大于b"
// 输出"a大于b"
print(str)
~~~
**9.nil合并运算符**
nil合并运算符:??,它的格式如下:
~~~
a ?? b
~~~
简单来说就是如果a为nil,则程序会返回b的值
~~~
let dfstr="九阴真经"
var str:String?
// 输出"九阴真经"
print(str ?? dfstr)
~~~
Swift快速入门(二)基本数据类型
最后更新于:2022-04-01 09:50:55
相关文章
[Swift快速入门(一)第一个Swift程序](http://blog.csdn.net/itachi85/article/details/50531727)
**1.变量和常量**
#### 声明常量和变量
Swfit是强类型的语言,Swift要求所有的变量和常量必须先声明后使用。
声明变量需要使用var,声明常量则需要使用let
~~~
var 变量名[:类型] =初始值
let 常量名[:类型] =初始值
~~~
下面来进行举例:
~~~
// 声明变量时显式指定类型
var age : Int
// 声明变量时指定初始值,编译器会根据初始值确定该变量的类型为String
var game= "九阴真经"
// 显式指定的类型与初始值的类型一致,声明变量正确
var age1: Int = 30;
// 显式指定的类型与初始值的类型不一致,声明变量失败
var game1 : String = 500;
// 定义常量,没有显式指定类型,编译器根据初始值确定常量的类型
let maxAge = 120
// 定义常量时,既显式指定常量的类型,也指定常量的初始值
let game2: String = "九阴真经"
~~~
#### 输出常量和变量
可以用print函数来输出当前常量或变量的值:
~~~
print(game) //九阴真经
~~~
Swift 用字符串插值(string interpolation)的方式把常量名或者变量名当做占位符加入到长字符串中,Swift 会用当前常量或变量的值替换这些占位符。将常量或变量名放入圆括号中,并在开括号前使用反斜杠将其转义:
~~~
print("game的值为:\(game)") //game的值为:九阴真经
~~~
**2.整型**
整数就是没有小数部分的数字,比如23和-23。整数可以是有符号(正、负、零)或者无符号(正、零)。
Swift 提供了8,16,32和64位的有符号和无符号整数类型。这些整数类型和 C 语言的命名方式很像,比如8位无符号整数类型是UInt8,32位有符号整数类型是Int32。就像 Swift 的其他类型一样,整数类型采用大写命名法。
####整型范围
你可以访问不同整数类型的min和max属性来获取对应类型的最大值和最小值:
~~~
let minValue = UInt8.min // minValue为 0
let maxValue = UInt8.max // maxValue为 255
~~~
####Int型与UInt型
Int型占的内存和当前的平台原生字长相同:对于32位平台,Int型与Int32型的长度相同,对于64位平台,Int型与Int64型的长度相同。此外Swift还支持对无符号整数的支持。但是尽量不要使用UInt,除非你真的需要存储一个和当前平台原生字长相同的无符号整数。除了这种情况,最好使用Int,即使你要存储的值已知是非负的。统一使用Int可以提高代码的可复用性,避免不同类型数字之间的转换,并且匹配数字的类型推测。即使是在32位平台上,Int可以存储的整数范围也可以达到-2147483648~2147483647,大多数时候这已经足够大了。
####整数数值表现形式
Swift整数数值有4种表示方式:
* 十进制:默认的就是十进制整数。
* 二进制:以0b开头的整数。
* 八进制:以0o开头的整数。
* 十六进制: 以0x开头的整数。
~~~
let decimalInteger = 17
let binaryInteger = 0b10001 // 二进制的17
let octalInteger = 0o21 // 八进制的17
let hexadecimalInteger = 0x11 // 十六进制的17
~~~
**3.浮点型**
浮点类型比整数类型表示的范围更大,可以存储比Int类型更大或者更小的数字。Swift 提供了两种有符号浮点数类型:
Double表示64位浮点数。当你需要存储很大或者很高精度的浮点数时请使用此类型。
Float表示32位浮点数。精度要求不高的话可以使用此类型。
#### 浮点数值表现形式
Swift的浮点数有3中表现形式:
* 十进制形式:这种形式就是平常简单的浮点数,例如 2.23,50.0。浮点数必须包含一个小数点,否则会被当作整数类型处理。
* 科学计数形式:例如2.23e2(2.23×10²),2.23E2(2.23×10²)。
* 十六进制数形式:这种形式的浮点数必须以0x开头,且需要使用p来代表指数部分,例如0x2.a2p2(0x2.a2×10²)
**4.数值型类型转换**
####整型之间的转换
不同整数类型的变量和常量可以存储不同范围的数字。Int8类型的常量或者变量可以存储的数字范围是-128~127,而UInt8类型的常量或者变量能存储的数字范围是0~255。如果数字超出了常量或者变量可存储的范围,编译的时候会报错:
~~~
// UInt 类型不能存储负数,所以会报错
let age: UInt = -1
// Int8 类型不能存储超过最大值的数,所以会报错
let big: Int8 = Int8.max + 1
~~~
要将一种数字类型转换成另一种,你要用当前值来初始化一个期望类型的新数字,这个数字的类型就是你的目标类型。在下面的例子中,常量two是UInt16类型,然而常量one是Uint8类型。它们不能直接相加,因为它们类型不同。所以要调用UInt16(one)来创建一个新的UInt16数字并用one的值来初始化,然后使用这个新数字来计算:
~~~
let two: UInt16 = 2
let one: UInt8 = 1
let third= two+ UInt16(one)
~~~
####整数和浮点数转换
整数和浮点数的转换必须显式指定类型:
~~~
let three = 3
let point = 0.141596
let add= Double(three) + point // add等于3.14159,所以被推测为 Double 类型
~~~
当进行类型转换时要尽量向表数范围大的数据类型转换,这样的程序更安全些,而反过来转换可能会导致运行时的错误。Swift各种数值型表数范围由小到大顺序:Int8—Int16—Int32—Int64—Float—Double
**5.布尔型**
Swift有一个基本的布尔(Boolean)类型,叫做Bool,它的数值只能是true和false,不能用0或者是非0来代表。其他的数据类型也不能转换成Bool类型。
~~~
var isGame= true
var isShow= false
~~~
字符串”true”和”false”不会直接转换成Bool类型,但Bool类型变量可以插值到字符串中:
~~~
var str:String="\(isGame)是真的"
print(str)
~~~
**6.元组类型**
####定义元组类型变量
元组(tuples)把多个值组合成一个复合值。元组内的值可以使任意类型,并不要求是相同类型。
~~~
// 定义元组变量,并指定初始值,系统推断该元组类型为(Int, Int, String)
var game= (1, 2 , "九阴真经")
// 使用元组类型来定义元组变量
var score : (Int , Int , String , Double)
// 为元组变量赋值时必须为所有成员都指定值
score = (98 , 89 , "及格" , 20.4)
~~~
元组类型的成员可以再次是元组:
~~~
var test : (Int , (Int , String))
test = (20 , (15 , "大航海时代"))
~~~
输出元组:
~~~
print("game元组的值为:\(game)")
print("score元组的值为:\(score)")
print("test元组的值为:\(test)")
~~~
####获取元组中的元素值
Swift允许通过下表来访问元组的单个元素,元组的下标从0开始。
~~~
print("game元组的排名元素为:\(game.0)")
print("game元组的名称元素为:\(game.2)")
print("test元组的第2个元素的第2个元素为:\(test.1.2)")
~~~
####为元组中的元素命名
定义元组时也可以使用key:value的形式来定义元组,这种形式相当于为每个元素都指定了名字,并且指定名字有更好的可读性:
~~~
// 使用元组类型来定义元组变量
var score : (java:Int , swift:Int , oc:String , ruby:Double)
// 简单为每个元素指定值,此时必须按顺序为每个元素指定值
score = (99 , 60 , "及格" , 20.1)
// 通过key为元组的元素指定值,在这种方式下,元组内各元素的顺序可以调换
score = (oc:"及格" , swift:60 , java:99 , ruby:20.1)
~~~
**7.可选类型**
####可选类型与值缺失
在任何已有类型的后面紧跟?就可以代表是可选类型,可选类型的变量用于处理“值缺失”。
我门先来看看如下代码:
~~~
var str = "九阴真经"
var num :Int = str.toInt()//会报错
var num1: Int? = str.toInt()//正确的代码
~~~
第二行代码会报错,因为“九阴真经”这个String类型无法转换成Int类型,如果str等于数字型的字符串则会转换成功(如var str = “11”)。转换失败时,我们无法返回Int值,这就是”值缺失”的情况,因此在这里必须使用Int?类型的变量来储存转换结果,所以第三行代码是正确的。
Swfit用nil来代表”值缺失”,因此上面的num1变量的值为nil。
需要注意的是,只有可选类型的变量和常量才能接收nil,非可选类型的变量和常量不能接收nil。
####强制解析
Int?类型与Int类型不是相同的类型,程序不能把Int?类型的值当作Int类型的。为了获取可选类型的实际存储的值,我们可以在可选类型的值后面加上“!”号。这个叹号表明:已知该可选变量有值,请提取其中的值,这种添加叹号进行解析的方法称之为强制解析。
~~~
var str : String? = "九阴真经"
// str是String?类型的,不能赋值给String类型的s变量
var s : String = str//会报错
~~~
上面的例子会报错,如果我们这样写则不会有问题:
~~~
var s : String = str!
print(s)
~~~
强制解析必须是可选类型的变量或者常量确实有值时才能够解析成功,否则会报错。为了去报强制解析不会导致运行是错误,Swift提供了if语句来判断可选类型是否有值,因此上面的语句改为如下的形式比较合适:
~~~
var str : String? = "九阴真经"
if str != nil
{
// 该值是String类型,因此可赋值给String类型的s变量
var s : String = str!
print(s)
}else{
print("str为nil,不能强制解析")
}
~~~
####隐式可选类型
隐式可选就是在任意的已有类型后面添加“!”。拿Int类型举例,Int?和Int!的区别就是:当程序获取Int?类型的值时,程序必须在变量名后添加“!”后缀来进行强制解析,而Int!则不需要,Swift会自动的执行隐式解析:
~~~
var s1: String? = "九阴真经"
// 对于String?可选类型,必须使用感叹号执行强制解析
var tmp : String = s1!
var s2 : String! = "大航海时代"
// 对于String!隐式可选类型,无需使用感叹号执行强制解析
var tmp2 : String = s2
~~~
需要注意的是隐式可选类型的值如果没有值的情况下,如果程序尝试获取该值同样会导致运行时错误,和强制解析一样,我们用if语句来判断隐式可选类型是否有值:
~~~
var str : String! = "大航海时代"
if str != nil {
// 对于String!隐式可选类型,无需使用感叹号执行强制解析
var s : String = str
print(s)
}else{
print("s为nil,不能强制解析")
}
~~~
####可选绑定
可选绑定用来判断可选是否包含值,如果包含就把值赋给一个临时常量或者变量。可选绑定一般用在 if 和 while 语句中,对可选的值进行判断并把值赋给一个常量或者变量。
~~~
var str : String! = "九阴真经"
// 如果可选变量str有值,将值赋值给tmp变量。
if var tmp = str
{
print("str的值为:\(tmp)")
}else{
print("str的值为nil,不能解析!")
}
~~~
**8.字符和字符串**
Swift使用Character来代表字符,String来代表字符串,字符串表示一个有序的字符集合。
####字符类型
Swift采用Unicode字符集来存储字符,字符必须使用双引号来包起来。
定义字符型的值有三种表示形式:
* 直接通过单个字符来指定字符常量,如“A”,”3”。
* 通过转义字符表示特殊字符常量,如“\n”,”\r”。
* 使用\u{n}的Unicode形式,其中n代表一个1~8的十六进制数。
swift常用的转义字符:
\0 空字符
\ 反斜杠
\ t 制表符
\n 换行符
\r 回车符
\” 双引号
\’ 单引号
####字符串类型
创建字符串:
~~~
var str="九阴真经"
var name:String="九阴真经"
~~~
字符串其实是一个结构体,因此我们可以调用结构体的构造器来创建字符串:
~~~
var str=String()//创建空字符串
var str=String("九阴真经")
~~~
####字符串可变性
在oc中有NSSting和NSMutableString来分别表示不可变和可变的字符串,Swift中只提供了String类型,Swift通过常量和变量来区分字符串是否可变:
~~~
var mutableStr="可变字符串"
let immutableStr="不可变字符串"
~~~
####字符串比较
Swift提供了3种方式来比较字符串:
* 字符串相等 ==
* 前缀相等 hasPrefix()
* 后缀相等 hasSuffix()
~~~
var str="jiuyinzhenjing"
var hasPrefix:Bool=str.hasPrefix("jiu")
print(hasPrefix)//结果为true
~~~
**9.类型别名**
Swift提供了类型别名为已有类型指定另一个名字,用typealias来定义类型别名:
~~~
typealias UintMin=Unit16
var max=UintMin.max//相当于取Unit16类型的最大值
print(max)//结果为65535
~~~
在这里不建议用类型别名,会使程序可读性降低。
Swift快速入门(一)第一个Swift程序
最后更新于:2022-04-01 09:50:52
**1. 本系列说明**
本系列只是一个Swift快速入门的教程,并没有详尽的介绍Swift,Swift也并不是一个简单的编程语言,所以要想详尽的系统的学习Swift,本系列并不适合你,此系列只是让开发者可以快速的用Swift来进行开发。另外学习本系列并不需要obj-c的知识,但是如果你想开发iOS,obj-c是必须要学的,因为Swift并不能很快的替代obj-c。另外本系列基于OS X EI Captitan 10.11.2,Xcode7.2。
**2. Swift介绍**
Swift,苹果于2014年WWDC(苹果开发者大会)发布的新开发语言,可与Objective-C共同运行于Mac OS和iOS平台,用于搭建基于苹果平台的应用程序。Swift吸收了众多现代编程语言的优点,尽力的提供简洁的编程语言和强大的功能。
**3. 第一个Swift程序**
Swift源文件的第一行可执行的代码就是Swift的程序的入口:
~~~
print("Hello World")
~~~
Swift程序的执行语句可以无须任何符号作为结束,Swift把每行代码作为了一个语句。但是如果在一行写了多个Swift语句则应该用”;”来作为语句的结束符。
~~~
print("Hello");print("World")
~~~
笔者还是建议用”;”来作为语句的结束符,这样可读性更强。
**3. Playground工具介绍**
Playground是一个简单的测试环境,主要是用于快速测试Swift语法功能和验证API功能,并不是用来进行实际开发应用。如果开发者对Swift语法功能不太确定,则可以用Playground来测试代码,其次Playground也可以用来验证某个函数,类的功能。
首先我们启动Xcode,选中Playground
![这里写图片描述](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-09_56dfc829345e3.jpg "")
接着在Name文本框输入Playground的名字
![这里写图片描述](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-09_56dfc8295d207.jpg "")
Playground保存成功后就会看到下面的编辑界面,左边是编辑界面,当开发者在左边编写代码,定义变量和常量之后,即可在右边是实时的看到变量或常量的值。我们将上面将的代码写进去就会看到,右边显示”Hello World”说明我们的代码没有问题。下面是运行按钮,点击运行按钮,控制台输出Hello World,第一个Swift程序就完成了。
![这里写图片描述](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-09_56dfc8297588b.jpg "")
**4. 用swiftc编译Swift程序**
swiftc的命令基本格式是
~~~
swiftc -o <生成文件> <源程序>
~~~
我们用文本编辑工具(我用的是Notepad+)在里面写上print(“Hello World”),保存在桌面取名为hello.swift
打开终端程序,进入桌面目录,输入如下命令:
~~~
swiftc -o hello.out hello.swift
~~~
我们会发现桌面生成了hello.out文件,接下来我们执行命令
~~~
./hello.out
~~~
这个命令会执行当前目录下的hello.out程序,执行该程序会看到输出Hello World
上述的编译,运行完整过程:
![这里写图片描述](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-09_56dfc8298ac65.jpg "")
本篇先到这里,接下来会讲Swift的基本语法。
ios学习笔记(六)使用UIScrollView嵌套UIView子类
最后更新于:2022-04-01 09:50:50
完成这一功能的前提是,你应该先安装好我上一节所说道的window-Based Application模版:
教程地址: http://blog.csdn.net/itachi85/article/details/7706549
接着我们要新建一个window-Based Application 模版
我们创建一个名为HypnosisView的objetctive-C class文件:
HypnosisView.h:
~~~
#import <Foundation/Foundation.h>
@interface HypnosisView : UIView
{
}
@end
~~~
HypnosisView.m:
在这个文件中我们加入了绘制了一个同心圆的图形
~~~
#import "HypnosisView.h"
@implementation HypnosisView
- (void)drawRect:(CGRect)rect
{
// 获取绘图区域
CGRect bounds = [self bounds];
// 计算中心点
CGPoint center;
center.x = bounds.origin.x + bounds.size.width / 2.0;
center.y = bounds.origin.y + bounds.size.height / 2.0;
// 计算中心点至边界角的距离
float maxRadius = hypot(bounds.size.width, bounds.size.height) / 2.0;
// 获取绘图所需要的上下文
CGContextRef context = UIGraphicsGetCurrentContext();
// 用10点的宽度来绘制所有的线条
CGContextSetLineWidth(context, 10);
// 线条颜色设为淡灰
[[UIColor lightGrayColor] setStroke];
// 绘制同心圆
for (float currentRadius = maxRadius; currentRadius > 0; currentRadius -= 20)
{
CGContextAddArc(context, center.x, center.y,
currentRadius, 0.0, M_PI * 2.0, YES);
CGContextStrokePath(context);
}
NSString *text = @"hi: i am henrymorgen.";
// 获取绘图所需要的字体
UIFont *font = [UIFont boldSystemFontOfSize:28];
// 计算绘图位置
CGRect textRect;
textRect.size = [text sizeWithFont:font];
textRect.origin.x = center.x - textRect.size.width / 2.0;
textRect.origin.y = center.y - textRect.size.height / 2.0;
// 将当前上下文的填充色设为黑色
[[UIColor blackColor] setFill];
[text drawInRect:textRect
withFont:font];
}
@end
~~~
接着我们配置代理 AppDelegate.h:
~~~
#import <UIKit/UIKit.h>
@class HypnosisView;
@interface HypnosisterAppDelegate : NSObject
<UIApplicationDelegate, UIScrollViewDelegate> {
HypnosisView *view;
}
@property (nonatomic, retain) IBOutlet UIWindow *window;
@end
~~~
AppDelegate.m:
在代理中我们添加了ScrollView,并将先前的HypnosisView添加到ScrollView中
~~~
#import "HypnosisterAppDelegate.h"
#import "HypnosisView.h"
@implementation HypnosisterAppDelegate
@synthesize window=_window;
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
CGRect wholeWindow = [[self window] bounds];
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:wholeWindow];
[[self window] addSubview:scrollView];
// 将视图的大小设为窗口的二倍
CGRect reallyBigRect;
reallyBigRect.origin = CGPointZero;
reallyBigRect.size.width = wholeWindow.size.width * 2.0;
reallyBigRect.size.height = wholeWindow.size.height * 2.0;
[scrollView setContentSize:reallyBigRect.size];
// 在UIScrollView对象里居中
CGPoint offset;
offset.x = wholeWindow.size.width * 0.5;
offset.y = wholeWindow.size.height * 0.5;
[scrollView setContentOffset:offset];
// 启用缩放功能
[scrollView setMinimumZoomScale:0.5];
[scrollView setMaximumZoomScale:5];
[scrollView setDelegate:self];
// 创建视图
view = [[HypnosisView alloc] initWithFrame:reallyBigRect];
[view setBackgroundColor:[UIColor clearColor]];
[scrollView addSubview:view];
[scrollView release];
[[UIApplication sharedApplication] setStatusBarHidden:YES
withAnimation:UIStatusBarAnimationFade];
[[self window] makeKeyAndVisible];
return YES;
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return view;
}
- (void)dealloc
{
[view release];
[_window release];
[super dealloc];
}
@end
~~~
最后运行一下看下效果:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-09_56dfc8291309e.png)
http://blog.csdn.net/itachi85/article/details/7706549
ios学习笔记(五)xcode4.3.2中添加Window-Based Application模版
最后更新于:2022-04-01 09:50:48
在新的ios sdk中苹果去掉了该模版,并会默认选择storyboard和自动引用计数,但是当我们这些初学者去学习时却发现现在的教程和书籍都是建立在Window-Based Application模版上的,着实郁闷。在《iOS编程第二版》中作者为我们建造了Window-Based Application模版,让我们看看如何去添加该模版:
1.下载模版 www.bignerdranch.com/solutions/Templates.zip
2.在finder中选择前往菜单中的“前往文件夹”输入 “~/Library/Developer/Xcode/”
3.将下载后的文件解压将Templates放入~/Library/Developer/Xcode/ 中
4.重启xcode
ios学习笔记(四)收回软键盘的两种方式
最后更新于:2022-04-01 09:50:46
这次讲的内容很简单:
1.首先我们还是创建一个Single View Application,然后打开MainStoryboard_iphone.storyboard,在里面放入俩lable和两个TextFiled:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-09_56dfc828b925f.png)
2.接着开始写代码:ViewController.h:
~~~
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController{
UITextField *nameField;
UITextField *numberField;
}
@property (nonatomic,retain) IBOutlet UITextField *nameField;
@property (nonatomic,retain) IBOutlet UITextField *numberField;
- (IBAction)backgroundTap:(id)sender;
- (IBAction)textFiledReturnEditing:(id)sender;
@end
~~~
ViewController.m:
~~~
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
@synthesize nameField;
@synthesize numberField;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
//点击屏幕空白view时触发的事件
- (IBAction)backgroundTap:(id)sender{
[nameField resignFirstResponder];//通知文本失去第一响应者状态
[numberField resignFirstResponder];
}
//点击return时触发的事件ß
- (IBAction)textFiledReturnEditing:(id)sender {
[sender resignFirstResponder];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
} else {
return YES;
}
}
@end
~~~
3.接着我们连接操作和输出口:
将背景view的类别设置为UIControl,这样我们就能对屏幕的事件进行处理了,将Control的touch down输出连接到backgroundTap事件上,因为点击软键盘会触发did end on exit,那我们就把两个textFiled的did end on exit输出连接到textFiledReturnEditing事件上。当然我们不要忘记将两个textFiled控件的输出与ViewController的相应控件接口连接在一起。
4.运行程序看看效果:
点击textFiled时:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-09_56dfc828caaa6.png)
点击return或点击界面空白时:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-09_56dfc828ec54d.png)
ios学习笔记(三)UISlider与UISwitch控件
最后更新于:2022-04-01 09:50:43
1 首先我们还是创建一个Single View Application,然后打开MainStoryboard_iphone.storyboard,在IB中添加一个UISlider控件和一个Label,这个Label用来显示Slider的值。
选中新加的Slider控件,打开Attribute Inspector,修改属性值,设置最小值为0,最大值为100,当前值为0.5,并确保勾选上Continuous,如下图:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-09_56dfc8287394c.png)
接着我们放上UISwitch控件,就是很像开关的那种控件,它只有两个状态:on和off,全都放上去效果就是这样的:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-09_56dfc828872d8.png)
2.好了我们开始写代码喽:ViewController.h:
~~~
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController{
UILabel *sliderlabel;
UISwitch *leftSwitch;
UISwitch *rightSwitch;
}
@property (nonatomic,retain) IBOutlet UILabel *sliderlabel;
@property (nonatomic,retain) IBOutlet UISwitch *leftSwitch;
@property (nonatomic,retain) IBOutlet UISwitch *rightSwitch;
- (IBAction)sliderChanged:(id)sender;
- (IBAction)switchChanged:(id)sender;
@end
~~~
接着是实现 ViewController.m:
~~~
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
@synthesize sliderlabel;
@synthesize leftSwitch;
@synthesize rightSwitch;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
} else {
return YES;
}
}
- (IBAction)sliderChanged:(id)sender{
UISlider *slider=(UISlider*)sender;
int progressAsInt=(int)(slider.value+0.5f);
NSString *newText=[[NSString alloc] initWithFormat:@"%d",progressAsInt];
sliderlabel.text=newText;
[newText release];
NSLog(@"%d",progressAsInt);
}
- (IBAction)switchChanged:(id)sender{
UISwitch *whichSwich=(UISwitch *)sender;
BOOL setting=whichSwich.isOn;
[leftSwitch setOn:setting animated:YES];
[rightSwitch setOn:setting animated:YES];
}
- (void)dealloc{
[sliderlabel release];
[leftSwitch release];
[rightSwitch release];
[super dealloc];
}
@end
~~~
3.剩下的就是连接操作和输出口:
将slider控件的value changed事件与sliderChanged方法连接在一起,将swich控件的value changed事件与swichChanged方法连接在一起,当然还要把lable控件和swich控件的输出与ViewController的相应控件接口连接在一起。
最终实现的效果如下面两张图:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-09_56dfc82897d6b.png)
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-09_56dfc828a6a80.png)
ios学习笔记(二)xcode 4.3.2下实现基本交互
最后更新于:2022-04-01 09:50:41
想必大家都阅读过iphone4与ipad2开发基础教程吧,这本书的xcode与现在的最新版本有些区别,去掉了view base application,只有比较接近的single view application.
首先我们创建一个single view application,注意这里我们不用自动引用计数。
接着我们点击工程列表中的MainStoryboard_iphone.storyboard 来编辑界面:
我们创建两个按钮和一个用来输出的空白文本:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-09_56dfc827d2f9a.png)
目录结构与视图结构:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-09_56dfc827e3941.png)
2.接着我们写代码来用来与IB界面编辑器来进行连接:在这里我们可以认为IBOutlet是与IB交互的输出,而IBAction则是IB交互的事件。
先编写ViewContoller.h:
~~~
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
{
}
@property (nonatomic,retain) IBOutlet UILabel * statusText;
-(IBAction)buttonPressed:(id)sender;
@end
~~~
接着在ViewContoller.m来实现功能:
~~~
#import "ViewController.h"
@implementation ViewController
@synthesize statusText;
-(IBAction)buttonPressed:(id)sender
{
NSString *title = [sender titleForState:UIControlStateNormal];//sender用于获得了不同的button的文字 titleForState是根据button状态获取文字的函数
NSString *newText = [[NSString alloc] initWithFormat:@"%@ button pressed.", title];//将title中的文字放入newText中
statusText.text = newText;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidUnload
{
[super viewDidUnload];
self.statusText = nil;
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
} else {
return YES;
}
}
- (void)dealloc
{
[statusText release];
[super dealloc];
}
@end
~~~
接着我们把这些代码与IB连接起来:
选择MainStoryboard_iphone.storyboard 右击View Controller Scene中的 Buton,选择Touch down与界面的
bottonPressed相连接:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-09_56dfc82820845.png)
接着将lable和statusText连接在一块:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-09_56dfc82839c63.png)
最后运行程序,点击botton看看效果:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-09_56dfc8284e99a.png)
ios学习笔记(一)xcode 4.3.2下创建第一个ios项目
最后更新于:2022-04-01 09:50:39
由于现在的xcode已经升级到4.X,现在国内的翻译书籍只讲的都是基于3.x所以在建立工程时会有一些小的不同。
XCode 4 以后,项目模版中没有了 Window-based Application,在这里我们可以选择 Empty Application. 如下图的选择:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-09_56dfc81a929f0.png)
设置完项目名称后,我们就可以看见如下界面:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-09_56dfc8273bcb4.png)
这时需要我们创建 MainWindow.xib,这个就是界面文件跟android的初始的main.xml差不多
我们在supporting Files下新建一个 window类型的xib,命名为:MainWindow.xib, 如下图:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-09_56dfc827593fb.png)
好的,马上快完成了,接着从Libray中拖动一个lable到界面上,并在lable输入些文字:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-09_56dfc8277cc3f.png)
最后别忘记设置 应用的主界面为MainWindow:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-09_56dfc8279fa6f.png)
大大功告成了,按command+s保存,点击run图标运行程序:当然别忘了把运行的设备选为iphone啊= =
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-09_56dfc827b75c1.png)
前言
最后更新于:2022-04-01 09:50:36
> 原文出处:[iOS开发指南](http://blog.csdn.net/column/details/iosdeveloper.html)
作者:[itachi85](http://blog.csdn.net/itachi85)
**本系列文章经作者授权在看云整理发布,未经作者允许,请勿转载!**
# iOS开发指南
> iOS开发指南