[TOC]

入门

  • 一、修饰符
  • 二、通知、代理、block

一、修饰符

Swift基础部门:http://www.swift51.com/swift4.0/chapter2/01_The_Basics.html

修饰符:

修饰符 所修饰的属性或者方法的作用范围
private 只能在当前类里访问
fileprivate 在当前的Swift源文件里可以访问
internal
(默认访问级别)
此修饰符可写可不写
在源代码所在的整个模块都可以访问。
①如果是框架或者库代码,则在整个框架内部都可以访问,框架由外部代码所引用时,则不可以访问。
②如果是App代码,也是在整个App代码,也是在整个App内部可以访问。
public 可以被任何人访问。
①其他module中不可以被override和继承,
②而在module内可以被override和继承
open 可以被任何人使用,包括override和继承

访问顺序:
现在的访问权限则依次为:open > public > internal > fileprivate > private。

swift – 静态变量static

1
2
3
4
5
6
7
8
9
10
11
12
class ViewController: UIViewController {
//静态变量 swift中的static静态变量,只能在这里声明,不能在方法中声明,会报错
static var i : Int = 1

override func viewDidLoad() {
super.viewDidLoad()

//调用静态变量
//print(self.i) 错
print(ViewController.i) //这样调用
}
}

懒加载 & Readonly

1、lazy关键字修饰一个变量就可以实现懒加载
2、懒加载的本质是,在第一次使用的时候使用调用,只会赋值一次

示例:

1
2
3
4
5
//lazy var btn : UIButton = UIButton();
lazy var btn : UIButton = {
let btn = UIButton()
return btn
}()

ReadOnly

Swift如何优雅的的设置只读(readOnly)属性

优雅地使用 Selector - Swift

截取字符串

参考文章:

修改函数参数的值/让方法参数可修改方法

在swift中,我们常常对数据进行一些处理。因为swift的计算属性,所以如果不是大量重复性处理,基本可以在set及didSet中改变原数据的一些状态。但需要用到同样的算法处理大量数据的时候,仍然需要写方法来解决。在如C一类的传统语言中,指针变量能轻易帮我们处理并直接修改掉原数据,而apple本身期望siwft中尽量减少指针的出现,因此,swift常规方法中经常用到的是值传递。值传递最明显的后果便是无法对原数据进行直接修改。如果我们需要处理后的数据结果,那么就需要重新定义一个变量来接收值。在原数据被废弃的情况下,这样既增多了代码量,也产生了空间大量浪费。因此 siwft提供了关键字修饰inout来申明数据地址传递,也称之为引用传递。在siwft3.0中 inout的位置发生了改变,处于标签位置,不过其作用相同。具体作用如下图代码:

其他参考:swift之inout

举例:

1
2
3
4
5
6
func show(with fixHeight: inout CGFloat, blankBGColor: UIColor) {
let maxHeight: CGFloat = UIScreen.main.bounds.height-60
if fixHeight > maxHeight {
fixHeight = maxHeight
}
}
1
2
3
4
5
6
func addTitle(text: String? = "") {
// 直接在方法中参数里赋默认值就好
//if text == nil {
// text = ""
//}
}

二、通知、代理、block

什么时候用通知,什么时候用代理,什么时候用block
通知 : 两者关系层次太深,八竿子打不着的那种最适合用通知.因为层级结构深了,用代理要一层一层往下传递,代码结构就复杂了

代理 : 父子关系,监听的方法较多的时候使用

block : 父子关系,监听的方法较少的时候使用

1、代理

  • 定义swift中代理的协议
1
2
3
4
5
6
7
// swift 中的代理必须继承自NSObjectProtocol
protocol VisitorViewDelegate : NSObjectProtocol
{
// 代理中的方法默认必须实现,有可以不实现的情况,以后整理
func visitorViewDidClickRegisterBtn(visitorView : VisitorView)
func visitorViewDidClickLoginBtn(visitorView : VisitorView)
}
  • 声明代理
1
2
// 代理属性,与OC一样,用weak修饰
weak var delegate : VisitorViewDelegate? // 可选类型,代理可以有也可以没有
  • 在按钮点击的事件中执行代理方法
1
2
3
4
5
6
7
8
9
10
11
12
// 注册按钮的点击
@IBAction func registerBtnClick(sender: UIButton) {
// 监听到点击,通知代理做事情
// 代理中的方法默认是必须实现的(也有可选的,后面再说),所以这里没有判断代理有没有实现相应的方法
delegate?.visitorViewDidClickRegisterBtn(self)
}

// 登录按钮的点击
@IBAction func loginBtnClick(sender: UIButton) {
// 监听到点击,通知代理做事情
delegate?.visitorViewDidClickLoginBtn(self)
}
  • 代理的具体实现

    swift中为了让方法分类更清晰,实现代理或者数据源的方法单独写到分类中

1
2
3
4
5
6
7
8
9
10
11
12
13
// MARK: - VisitorViewDelegate代理方法
// swift 中为了区分不同类型的代理方法或者数据源方法,通过extension实现了更好的区分
extension BaseTableViewController: VisitorViewDelegate
{
func visitorViewDidClickRegisterBtn(visitorView : VisitorView) {
ChaosLog("")
}

func visitorViewDidClickLoginBtn(visitorView : VisitorView) {

ChaosLog("")
}
}

2、block

作为类属性:

1
var clickHandle: ((_ sheetModel: CJDemoActionSheetModel, _ selectIndex: NSInteger)->())?

作为函数变量:

1
2
3
init(sheetModels:[CJDemoActionSheetModel], clickHandle: @escaping (_ sheetModel: CJDemoActionSheetModel, _ selectIndex: NSInteger)->()) {

}

其他参考文章:

其他

获取类名

1
2
CJDemoActionSheetTableViewCell.self
UIViewController.self

如何在int和float之间的算术在Swift?

1
2
3
4
var myInt = 5;
var myDouble = 3.4;
var doubleResult = Double(myInt) + myDouble;
var intResult = myInt + Int(myDouble)

内存管理

CFRelease

苹果的一些底层框架返回的对象有的是自动管理内存的(annotated APIs),有的是不自动管理内存。

如果一个函数名中包含CreateCopy,则调用者获得这个对象的同时也获得对象所有权,返回值Unmanaged需要调用takeRetainedValue()方法获得对象。调用者不再使用对象时候,Swift代码中不需要调用CFRelease函数放弃对象所有权,这是因为Swift仅支持ARC内存管理,这一点和OC略有不同。

上文摘自:https://www.jianshu.com/p/103591adc3d1 中 CFRoopLoop使用 的使用

Swift GCD延迟加载

详细参考:

swift 自定义view的初始方法

swift中的@objc的作用

Swift枚举的全用法

iOS 国际化全解-swift与OC