var
定义变量,设置之后可以修改let
定义常量,设置之后不可以修改;
print()
替代 OC 中的 NSLog
print
的性能更好,后面会演示// 定义变量
var i = 10
print(i)
i = 15
print(i)
let j = 20
// 常量一经定义不能自改数值
// j = 25
print(j)
注意点: 在Swift开发中, 一般情况下先用let, 只要需要修改数据时才用var, 使用let的好处, 可以避免数据被修改, 可以保证数据安全性
类型推导:
类型转换:
let x = 10
let y = 10.5
let z: Double = 20
print(Double(x) + y)
print(x + Int(y))
print(y + z)
let number3: (Int, Double, Int, Double) = (10, 10.1, 9, 44.40)
number3.0
number3.1
number3.2
number3.3
Swift
中没有 C 语言中的非零即真
概念if
语句条件的 ()
可以省略{}
不能省略var i = 10
if i > 0 {
print("OK")
}
var a = 10
var b = 50
var result = a > b ? a : b
print(result)
在Swift中如果使用一个可选类型的变量/常量, 必须解包操作
格式:
let number: Optional = 10
print(number!)
let number2 = 10
let sum = number! + number2
可选类型注意点: 在开发中一般情况下尽量不要强制解包一个可选类型, 否则会引发错误
防止上述情况,使用注意
// Swift开发中推荐这种写法
if let temp = url
{
let request = NSURLRequest(URL: temp)
}
// Swift开发中推荐的for循环格式
for i in 0..<10
{
print(i)
}
var number = 0
while number < 10
{
print(number)
number++
}
var index = 0
repeat{
print(index)
index++
}while index < 10
var arr: Array / var arr: [Int]
可变和不可变对应:var/let
定义数组 简写为:var arr = [1, 2]
arr[0]
for item in arr
{
print(item)
}
arr.append(3)
arr[1] = 9
arr.removeAtIndex(0)
var arr1 = [3, 5, 7]
arr += arr1
for item in arr[0..<2] // 0~1
{
print(item)
}
var dict: Dictionary
可变和不可变 var/let
注意: 将OC的{}换成了[]
企业开发中字典使用得最多的类型就是 [String: NSObject]类型
var dict2 = ["name": "l
s", "age": 30, "score": 99.9]
/// 定义并实例化字典
var dict = [String: AnyObject]()
dict["name"] = "zhangsan"
dict["age"] = 18
print(dict)
// 设置相同 key,之前的数值会被覆盖
dict["name"] = "lisi"
print(dict)
// 删除某一个 key
dict.removeValueForKey("age")
print(dict)
dict["title"] = "manager"
print(dict)
// 遍历字典(k, v可以随便写)
for (k, v) in dict {
print("\(k) -- \(v)")
}
// 合并字典
var dict2 = ["name": "wangwu", "age": 80, "title": "boss"]
for (k, v) in dict2 {
dict.updateValue(v, forKey: k)
}
print(dict)
注意点无论是数组还是字典, 只有相同类型才能赋值
let str = "我要飞的更High"
for s in str {
print(s)
}
let str1 = "zhangsan"
let str2 = "lisi"
str2 += str
str2
// 可以使用\()在字符串中插入任何数据
let name = "lnj"
let age = 30
let res = "name = \(name), age = \(age)"
res
// 输出:2015-10-09 03:04
let str3 = String(format: "%d-%02d-%02d %02d:%02d", arguments: [2015, 10, 9, 3, 4])
let str4 = "xiaomaguohe"
// as 就是把什么当做什么
(str4 as NSString).substringWithRange(NSMakeRange(4, 2))
func 函数名称(形参列表) ->返回值类型
{
代码
}
func sum(a: Int, b: Int) -> Int {
return a + b
}
如果没有返回值, -> 返回值
可以省略
1.没有参数没有返回值
func say() -> Void
{
print("hi")
}
say()
// 简写形式
func say2()
{
print("hi")
}
say2()
func sum(num1: Int, num2: Int)
{
print(num1 + num2)
}
sum(10, num2: 20)
func getNumber() -> Int
{
return 998
}
print(getNumber())
func sum2(num1: Int, num2: Int) -> Int
{
return num1 + num2
}
print(sum2(50, num2: 50))
func sum3(num1: Int, y num2: Int)
{
print("num1 = \(num1), num2 = \(num2)")
print(num1 + num2)
}
//sum3(10, num2: 20)
sum3(10, y: 20)
默认参数
常量参数和变量参数以及inout参数
func swap(inout a: Int, inout b: Int)
{
print("a = \(a), b = \(b)")
let temp = a
a = b
b = temp
print("a = \(a), b = \(b)")
}
func sum4(nums: Int..., temp: Int) -> Int
{
var sum = 0
for i in nums
{
sum += i
}
return sum + temp
}
sum4(1, 2, 3, temp: 10) // 输出结果:16
let value = 55
func test()
{
let number = 10
func demo()
{
print("----\(number), \(value)")
}
demo()
}
test()
// 如果该属性不是对象类型而是基本数据类型, 那么建议直接赋值为0
var name: String?
// 如果属性是基本数据类型, 并且是可选类型, 系统不会自动分配存储空间
var age: Int = 0
// Person()
override init() {
// 注意: 在构造方法中必须先初始化本类再初始化父类
name = "lnj"
age = 30
// 当我们重写一个类的构造方法时, 系统内部会帮我们调用super.init()
super.init()
}
init(name: String, age: Int)
{
self.name = name
self.age = age
// 以下这一句代码, 能不写就不写
// super.init()
}
init(dict: [String: AnyObject])
{
// 注意:Swift中如果想在构造方法中使用KVC转换模型, 必须先调用 super.init()
// 调用 super.init()的目的主要是为了给对象分配存储空间
super.init()
setValuesForKeysWithDictionary(dict)
}
// Swift中打印对象会调用下面这个属性
override var description: String {
// return "name = \(name), age = \(age)"
let property = ["name", "age"]
let dict = dictionaryWithValuesForKeys(property)
return "\(dict)"
}
注意: Swift开发中一般情况下不用导入头像文件, 因为只要所有的文件都在一个命名空间中那么就可以直接使用
默认情况下一个项目的命名空间就是项目名称, 而在同一个项目下的所有文件都在同一个命名空间中
var name: String?
{
// 在Swift开发中用以下两个方法代替OC中的重写setter方法
willSet{
print("赋值之前调用 \(newValue)")
}
didSet{
print("赋值之后调用 \(oldValue)")
}
}
var age: Int
{
// 在Swift中如果只重写了get方法, 那么该属性就是一个只读属性readOnly
// 如果一个属性只重写了get方法, 我们也称之为"计算型属性", 计算型属性是不具备存储能力的
// get{
// return 99
// }
// 如果只是想重写一个属性的get方法, 那么可以简写
return 99
}
类型: 返回值类型(^block名称)(形参列表)
值:
^(形参列表){
需要执行的代码
}
类型: (形参列表)->返回值类型
值:
{
(形参列表)->返回值类型
in
需要执行的代码
}
1. 完整写法
loadData ({ () -> () in
print("更新UI")
})
2.如果闭包没有形参, 那么in和in之前的代码都可以省略
loadData ({
print("更新UI")
})
3.如果闭包是函数的最后一个参数, 那么闭包可以写在函数()的后面
loadData (){
print("更新UI")
}
4.如果函数只有一个闭包参数, 那么函数的()可以省略
loadData {
print("更新UI")
}
注意: 在设置闭包属性是可选类型时一定更要用一个()括住闭包的所有的类型, 否则只是指定了闭包的返回值是可选的
// 错误写法: var callback: ()->()?
var callback: (()->())?
闭包循环引用
__weak == weak
__unsafe_unretained == unowned
__weak : 如果对象释放, 会自动设置为nil
__unsafe_unretained: 如果对象释放, 不会自动设置为nil
解决循环引用的方法
weak var weakSelf = self // 方法1
loadData { [unowned self] () -> () in // 方法2
// 只要一个对象释放就会调用deinit方法
deinit
{
print("88")
}
注意: 一定要记住闭包后面需要写上(), 代表执行闭包
lazy var listData: [String]? = {
()->[String]
in
print("---")
return ["ls", "zs", "why", "wsz"]
}()
// 开发中这样写
lazy var listData2: [String]? = {
print("---")
return ["ls", "zs", "why", "wsz"]
}()
static var onceToken: dispatch_once_t = 0;
static var _instance: NetworkTools?
class func shareNetworkTools() -> NetworkTools {
print(onceToken)
dispatch_once(&NetworkTools.onceToken, {
_instance = NetworkTools()
})
return _instance!
}
static let shareInstance: NetworkTools = NetworkTools()