- 函数的使用注意:
func sum(num1 : Int, num2 : Int) -> Int{
return num1 + num2
}
let result = sum(1, num2: 3)
注意一:内部参数和外部参数
//内部参数:在函数内部可以看到的参数,默认情况所有参数都是内部参数
//外部参数:在函数外部可以看到的参数名称就是外部参数,默认情况从第二个参数开始即是内部参数也是外部参数
//如果希望第一个参数也是外部参数,可以在标识符前给参数添
func sum(num1 num1 : Int, num2 : Int) -> Int{
return num1 + num2
}
let result = sum(num1: 3, num2: 5)
注意二:swift中可以设置默认参数
func goBuyCoffe(coffeeName : String = "雀巢") -> String{
return "\(coffeeName)咖啡买过来了"
}
goBuyCoffe("拿铁") //输出 "拿铁咖啡买过来了"
goBuyCoffe() //输出 "雀巢咖啡买过来了"
注意三:可变参数
//用...来表示可以添加多个参数 类型必须一致
func sum(num : Int...) -> Int {
var result = 0
for i in num {
result += i
}
return result
}
sum(1,2,3)
注意四:指针类型
var m = 20
var n = 10
//错误示范,因为此时是值传递,所以并未达到交换的效果
func swap(var num1 :Int , var num2 : Int) {
let temp = num1
num1 = num2
num2 = temp
}
swap(m, num2: n)
print("交换后m:\(m),n:\(n)")
//输出"交换后m:20,n:10\n"
//正确写法 加上inout关键字
var m = 20
var n = 10
func swap(inout num1 : Int , inout num2 : Int) {
let temp = num1
num1 = num2
num2 = temp
}
swap(&m, num2: &n)
print("交换后m:\(m),n:\(n)")
//输出"交换后m:10,n:20\n"
- swift中类的定义
注意:可以不指定父类
class Person: NSObject {
var age : Int = 0
}
let p = Person()
p.age = 18
p.setValuesForKeysWithDictionary(["age" : 18])
print(p.age)
//但是这么处理有一个不方便的地方,如果传入了事先没有定义的属性就会报错
p.setValuesForKeysWithDictionary(["name":"jack","age":16])
//为了解决这种 采用如下方法,添加一个新方法
//override:重写,如果写的某一个方法是对父类的方法进行的重写,那么必须在该方法前加上override
class Person: NSObject {
var age : Int = 0
override func setValue(value: AnyObject?, forUndefinedKey key: String) {
}
}
let p = Person()
//此时即使有无法识别的属性也不会报错
p.setValuesForKeysWithDictionary(["name":"jack","age" :16])
print(p.age)
- 定义类的属性
类的属性介绍
存储属性:存储实例的常量和变量
计算属性:通过某种方式计算出来的属性
类属性:与整个类自身相关的属性
存储属性
- 存储属性是最简单的属性,它作为类实例的一部分,存储实例的常量和变量
- 可以给存储属性提供一个默认值,也可以在初始化方法中对其进行初始化
- 下面是相关属性的写法
class Student: NSObject {
var age :Int = 0
var name :String? = nil //此处写不写等于nil 都是nil 可以简写var name :String?
var mathScore : Double = 0.0
var englishSocre : Double = 0.0
//定义计算属性:通过别的方式计算得到结果的属性
var averageScore : Double{
return (mathScore + englishSocre) * 0.5
}
//定义雷属性:类属性是和整个类相关的属性,而且是通过类名进行访问
static var courseCount : Int = 0
/*
//定义一个方法,可以返回平均成绩
func getScore() -> Double {
//在swift开发中,如果使用当前对象的某一个属性,或者调用当前对象的某一个方法时,可以直接使用,不需要加self
return (mathScore + englishSocre) * 0.5
}
*/
}
let stu = Student()
//给对象属性赋值
stu.age = 17
stu.name = "jack"
stu.mathScore = 89.0
stu.englishSocre = 58.0
//给类属性赋值
Student.courseCount = 2
print(stu.age)
if let name = stu.name{
print(name)
}
let averageScore = stu.averageScore
- 类的构造函数
构造函数的介绍:
- 构造函数类似于OC中的初始化方法:init方法
- 默认情况下创建一个类时,必然会调用一个构造函数
即便是没有编写任何构造函数,编译器也会提供一个默认的构–造函数 - 如果是继承自NSObject,可以对父类的构造函数进行重写
class Person: NSObject {
var name : String?
var age = 0
//构造函数中,如果明确super.init(),系统会帮助调用
override init() {
super.init()
print("-----")
}
//自定义构造函数
init(name : String , age : Int) {
//有歧义的时候可以通过self.来区分
self.name = name
self.age = age
}
/* 不推荐方法一
init(dict : [String : AnyObject]) {
//直接取值会报错cannot assign value of type 'AnyObject?' to type 'Int'
// name = dict ["name"]
// age = dict["age"]
//解决方法
方法一
let tempName = dict ["name"]//tempName是一个AnyObject类型,如何转为String?
name = tempName as? String
let tempAge = dict["age"]//tempAge是一个AnyObject类型,如何转为确定的类型
//let tempAge1 = tempAge as! Int//但此时强制解包可能会诱发错误,得继续处理
let tempAge1 = tempAge as? Int//先转成可选类型
if tempAge1 != nil {
age = tempAge1! //然后不为空再解包
}
//方法简化
if let tempAge = dict["age"] as? Int{
age = tempAge
}
}
*/
//方法二(推荐KVC)
init(dict :[String : AnyObject]){
super.init()//如果使用KVC,此处一定要手动调用 super.init(),因为系统帮忙调用是在后面调用,此处不立即先调用会报错
setValuesForKeysWithDictionary(dict)
}
override func setValue(value: AnyObject?, forUndefinedKey key: String) {
}
}
let p = Person()
let p1 = Person(dict : ["name" : "why", "height" : 1.88, "age" : 18])
print(p1.age)
print(p1.name)
- 属性监听
class Person: NSObject {
//属性监听器
var name : String? {
//属性即将改变时进行监听
willSet{
print(name)
}
didSet{
print(name)
}
}
}
let p = Person()
p.name = "jock"
闭包
闭包和OC中的block非常相似- OC中的block是匿名的函数
- swift中的闭包是一个特殊的函数
- block和闭包都经常用于回调
闭包的使用
一个小例子
代码
ViewController.swift
import UIKit
class ViewController: UIViewController {
var tools : HttpTool = HttpTool()
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
/*解决循环引用的方式一:
weak var weakSelf = self
tools.loadData { (jsonData) in
print(jsonData)
/* weakSelf? 如果前面的可选类型没有值,后面所有代码都不会执行
如果前面的可选类型有值,系统会自动将weakSelf解包
*/
weakSelf?.view.backgroundColor = UIColor.redColor()
}
*/
/*方式三:unowned相当于 _unsafe_unretained
tools.loadData {[unowned self] (jsonData) in
print(jsonData)
// 注意这种方式比较危险,一旦self为空值,就会崩溃
self.view.backgroundColor = UIColor.redColor()
*/
//方式二是对方式一的简化(推荐使用):
tools.loadData {[weak self] (jsonData) in
print(jsonData)
/* weakSelf? 如果前面的可选类型没有值,后面所有代码都不会执行
如果前面的可选类型有值,系统会自动将weakSelf解包
*/
self?.view.backgroundColor = UIColor.redColor()
}
}
deinit{
print("ViewController --deinit")
}
}
HttpTool.swift
import UIKit
class HttpTool: NSObject {
var callBack : ((jsonData : String) -> ())?
//闭包的类型:(参数列表)->(返回值类型)
func loadData(callBack:(jsonData : String) -> ()) {
self.callBack = callBack
dispatch_async(dispatch_get_global_queue(0, 0)) {
print("发送网络请求\(NSThread .currentThread())")
dispatch_sync(dispatch_get_main_queue(), {
print("获取到数据,并且进行回调\(NSThread .currentThread())")
callBack(jsonData: "jsonData数据")
})
}
}
}
- 懒加载
swift中懒加载的方式
(苹果的设计思想:希望所有的对象在使用时才真正加载到内存中)
和OC不同的是swift有专门的关键字来实现懒加载
last关键字可以用于定义某一个属性懒加载
懒加载的使用
格式
lazy var 变量 :类型 = {创建变量代码}()
//懒加载的本质是,在第一次使用的时候执行闭包,将闭包的返回值赋值给属性
//lazy的作用是只会赋值一次
lazy var array :[string] = {
() ->[String] in
return ["why","aaa","dvd"]
}()
- swift中tableView的简单使用
import UIKit
class ViewController: UIViewController {
// MARK:- 懒加载的属性 分组注释
lazy var tableview : UITableView = {
let tempTableView = UITableView()
return tempTableView
}()
// MARK:- 系统回调函数
override func viewDidLoad() {
super.viewDidLoad()
//1.添加tableview对象到控制器的view中
view.addSubview(tableview)
//2.设置tableView的frame
tableview.frame = view.bounds
//3.设置数据源
tableview.dataSource = self
//4.设置代理
tableview.delegate = self
}
}
//extension类似OC的category,也是只能扩充方法,不能添加属性(不绝对)
extension ViewController:UITableViewDelegate,UITableViewDataSource{
// MARK:- tableview的数据源和代理方法
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 20
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cellID = "cellID"
var cell = tableview.dequeueReusableCellWithIdentifier(cellID)
if cell == nil {
cell = UITableViewCell(style: .Default, reuseIdentifier: cellID)
}
cell?.textLabel?.text = "swift中的tableviewcell\(indexPath.row)"
return cell!
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
print("点击了cell")
}
}