swift之常用的修饰符、关键字

========@objc=============

 

@objc 使用介绍

在swift3中,编译器自动推断@objc,换句话说,它自动添加@objc 
在swift4中,编译器不再自动推断,你必须显式添加@objc

在swift 中 如果一个按钮添加点击方法 如果定义为Private  或者 定义为 FilePrivate 那么会在Addtaget方法中找不到私有方法

但是又不想把方法暴露出来,避免外界访问 ,那么可以在私有方法前加 @objc 修饰 那么它就能找到那个方法了 

   @objc 作用

    1 fileprivate 或者 private  保证方法私有 能在同一个类 或者 同一个文件(extension)中访问这个方法 如果定义为private  那么只能在一个类中访问 不能在类扩展中访问

    2 允许这个函数在“运行时”通过oc的消息机制调用

==============extension=======================

 

 

扩展声明使用关键字 extension:

extension SomeType {

    // 加到SomeType的新功能写到这里

}

一个扩展可以扩展一个已有类型,使其能够适配一个或多个协议,语法格式如下:

extension SomeType:SomeProtocol,AnotherProctocol {

    // 协议实现写到这里

}

========================================is和as 类型转换

 

Swift 语言类型转换可以判断实例的类型。也可以用于检测实例类型是否属于其父类或者子类的实例。

Swift 中类型转换使用 is 和 as 操作符实现,is 用于检测值的类型,as 用于转换类型。

类型转换也可以用来检查一个类是否实现了某个协议。

向下转型,用类型转换操作符(as? 或 as!)

当你不确定向下转型可以成功时,用类型转换的条件形式(as?)。条件形式的类型转换总是返回一个可选值(optional value),并且若下转是不可能的,可选值将是 nil。

只有你可以确定向下转型一定会成功时,才使用强制形式(as!)。当你试图向下转型为一个不正确的类型时,强制形式的类型转换会触发一个运行时错误。

 

var chemCount = 0

var mathsCount = 0

 

for item in sa {

    // 类型转换的条件形式

    if let show = itemas?Chemistry {

        print("化学主题是: '\(show.physics)',\(show.equations)")

        // 强制形式

    } else iflet example = itemas? Maths {

        print("数学主题是: '\(example.physics)', \(example.formulae)")

    }

}

 

 

类型转换用于检测实例类型是否属于特定的实例类型。

你可以将它用在类和子类的层次结构上,检查特定类实例的类型并且转换这个类实例的类型成为这个层次结构中的其他类型。

类型检查使用 is 关键字。

操作符 is 来检查一个实例是否属于特定子类型。若实例属于那个子类型,类型检查操作符返回 true,否则返回 false。

var chemCount = 0

var mathsCount = 0

for item in sa {

    // 如果是一个 Chemistry 类型的实例,返回 true,相反返回 false。

    if item isChemistry {

        ++chemCount

    } else if itemisMaths {

        ++mathsCount

    }

}

 

 

 

Swift为不确定类型提供了两种特殊类型别名:

  • AnyObject可以代表任何class类型的实例。
  • Any可以表示任何类型,包括方法类型(function types)。
 

========================访问控制修饰符===========================

 

协议也可以被限定在一定的范围内使用,包括协议里的全局常量、变量和函数。

访问控制基于模块与源文件。

模块指的是以独立单元构建和发布的 Framework 或 Application。在 Swift 中的一个模块可以使用 import 关键字引入另外一个模块。

源文件是单个源码文件,它通常属于一个模块, 源文件可以包含多个类和函数 的定义。

Swift 为代码中的实体提供了四种不同的访问级别:public、internal、fileprivate、private。

访问级别定义
public可以访问自己模块中源文件里的任何实体,别人也可以通过引入该模块来访问源文件里的所有实体。
internal可以访问自己模块中源文件里的任何实体,但是别人不能访问该模块中源文件里的实体。
fileprivate文件内私有,只能在当前源文件中使用。
private只能在类中访问,离开了这个类或者结构体的作用域外面就无法访问。

public 为最高级访问级别,private 为最低级访问级别。

除非有特殊的说明,否则实体都使用默认的访问级别 internal。

 

 

 

 

 

*************函数类型访问权限

函数的访问级别需要根据该函数的参数类型和返回类型的访问级别得出

下面的例子定义了一个名为someFunction全局函数,并且没有明确地申明其访问级别。

func someFunction() -> (SomeInternalClass,SomePrivateClass) {

    // 函数实现

}

函数中其中一个类 SomeInternalClass 的访问级别是 internal,另一个 SomePrivateClass 的访问级别是 private。所以根据元组访问级别的原则,该元组的访问级别是 private(元组的访问级别与元组中访问级别最低的类型一致)。

因为该函数返回类型的访问级别是 private,所以你必须使用 private 修饰符,明确的声明该函数:

private func someFunction() -> (SomeInternalClass,SomePrivateClass) {

    // 函数实现

}

将该函数申明为 public 或 internal,或者使用默认的访问级别 internal 都是错误的,因为如果这样你就无法访问 private 级别的返回值。

*****************枚举类型访问权限

枚举中成员的访问级别继承自该枚举,你不能为枚举中的成员单独申明不同的访问级别

 

比如,枚举 Student 被明确的申明为 public 级别,那么它的成员 Name,Mark 的访问级别同样也是 public:

实例

public enum Student {

    case Name(String)

    case Mark(Int,Int,Int)

}

 

var studDetails = Student.Name("Swift")

var studMarks = Student.Mark(98,97,95)

 

switch studMarks {

case .Name(let studName):

    print("学生名: \(studName).")

case .Mark(let Mark1,let Mark2,let Mark3):

    print("学生成绩: \(Mark1),\(Mark2),\(Mark3)")

}

 

子类的访问级别不得高于父类的访问级别。比如说,父类的访问级别是internal,子类的访问级别就不能申明为public。

 

 

常量、变量、属性不能拥有比它们的类型更高的访问级别。

比如说,你定义一个public级别的属性,但是它的类型是private级别的,这是编译器所不允许的。

同样,下标也不能拥有比索引类型或返回类型更高的访问级别。

如果常量、变量、属性、下标索引的定义类型是private级别的,那么它们必须要明确的申明访问级别为private:

常量、变量、属性、下标索引的Getters和Setters的访问级别继承自它们所属成员的访问级别。

Setter的访问级别可以低于对应的Getter的访问级别,这样就可以控制变量、属性或下标索引的读写权限。

 

==================可选项========

 

Swift 的可选(Optional)类型,用于处理值缺失的情况。可选表示"那儿有一个值,并且它等于 x "或者"那儿没有值"。

Swfit语言定义后缀?作为命名类型Optional的简写,换句话说,以下两种声明是相等的:

var optionalInteger: Int?
var optionalInteger: Optional<Int> optionalInteger: Int?
var optionalInteger: Optional<Int>

在这两种情况下,变量 optionalInteger 都是可选整数类型。注意,在类型和 ?之间没有空格。

Optional 是一个含有两种情况的枚举,None 和 Some(T),用来表示可能有或可能没有值。任何类型都可以明确声明为(或者隐式转换)可选类型。当声明一个可选类型的时候,要确保用括号给 ? 操作符一个合适的范围。例如,声明可选整数数组,应该写成 (Int[])? 写成 Int[]? 会报错。

当你声明一个可选变量或者可选属性的时候没有提供初始值,它的值会默认为 nil。

可选项遵照 LogicValue 协议,因此可以出现在布尔环境中。在这种情况下,如果可选类型T?包含类型为T的任何值(也就是说它的值是 Optional.Some(T) ),这个可选类型等于 true,反之为 false。

如果一个可选类型的实例包含一个值,你可以用后缀操作符 !来访问这个值,如下所示:

optionalInteger = 42
optionalInteger! // 42= 42
optionalInteger! // 42

使用操作符!去获取值为nil的可选变量会有运行时错误。

你可以用可选链接和可选绑定选择性执行可选表达式上的操作。如果值为nil,任何操作都不会执行,也不会有运行报错。

强制解析

当你确定可选类型确实包含值之后,你可以在可选的名字后面加一个感叹号(!)来获取值。这个感叹号表示"我知道这个可选有值,请使用它。"这被称为可选值的强制解析(forced unwrapping)。

 

============inout 关键字==================

 

 

一般默认在函数中定义的参数都是常量参数,也就是这个参数你只可以查询使用,不能改变它的值。

如果想要声明一个变量参数,可以在参数定义前加 inout 关键字,这样就可以改变这个参数的值了。

例如:

func  getName(_ name: inout String).........(_ name: inout String).........

 

==========static=======

static修饰的属性只能有类来调用

 

=============open=====

类似public

==============throw========

抛出异常

=========

swift51地址:http://www.swift51.com/swift4.0/chapter2/10_Properties.html

*****类似OC中#pragma mark 和 #waring的用法:https://blog.csdn.net/horisea/article/details/77064200、https://blog.csdn.net/micheal_zj/article/details/77324535

******extention:扩展

 

*******set和get的使用、willset、didset:https://blog.csdn.net/sinyui/article/details/78320418

********@escaping

闭包只有在函数中做参数时才会区分逃逸闭包和非逃逸闭包。

Swift 3.0之后,传递闭包到函数中的时候,系统会默认为非逃逸闭包类型(NonescapingClosures)@noescaping,逃逸闭包在闭包前要添加@escaping关键字。

从生命周期看两者区别:

非逃逸闭包的生命周期与函数相同:

1,把闭包作为参数传给函数;

2,函数中调用闭包;

3,退出函数。结束


逃逸闭包的生命周期:

1,闭包作为参数传递给函数;

2,退出函数;

3,闭包被调用,闭包生命周期结束

即逃逸闭包的生命周期长于函数,函数退出的时候,逃逸闭包的引用仍被其他对象持有,不会在函数结束时释放
 

********@ discardableResult

swift正常的方法如果有返回值的话,调用的时候必须有一个接收方,否则的话编译器会报一个警告,如果在方法前加上 @discardableResult 不处理的时候就不会有警告了。也可以用一个通配符接收方法返回值,可以达到同样的目的。https://blog.csdn.net/zx416632112/article/details/79015608

调用函数的时候忽略返回值,不会产生编译警告,所以函数被标注为@ discardableResult属性。

*********final

你可以通过把方法,属性或下标标记为final来防止它们被重写,只需要在声明关键字前加上final修饰符即可.你可以通过在关键字class前添加final修饰符(final class)来将整个类标记为 final 的。这样的类是不可被继承的,试图继承这样的类会导致编译报错.

 

*********indirect

你可以在枚举成员前加上indirect来表示该成员可递归

 

*********defer

使用defer语句在即将离开当前代码块时执行一系列语句。该语句让你能执行一些必要的清理工作,不管是以何种方式离开当前代码块的——无论是由于抛出错误而离开,或是由于诸如return、break的语句。例如,你可以用defer语句来确保文件描述符得以关闭,以及手动分配的内存得以释放。

defer语句将代码的执行延迟到当前的作用域退出之前。该语句由defer关键字和要被延迟执行的语句组成。延迟执行的语句不能包含任何控制转移语句,例如break、return语句,或是抛出一个错误。延迟执行的操作会按照它们声明的顺序从后往前执行——也就是说,第一条defer语句中的代码最后才执行,第二条defer语句中的代码倒数第二个执行,以此类推。最后一条语句会第一个执行

 

******option

在协议中使用 optional 关键字作为前缀来定义可选要求

****require

必须的

******@objc

可选要求用在你需要和 Objective-C 打交道的代码中。协议和可选要求都必须带上@objc属性。标记 @objc 特性的协议只能被继承自 Objective-C 类的类或者 @objc 类遵循,其他类以及结构体和枚举均不能遵循这种协议。
 

********@_exported

这里必须加上@_exported才能全局使用,

@_exported import Alamofire

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值