❤ swift语法的重难点-包含swiftJson

闭包部分的逃逸闭包和自动闭包 https://juejin.cn/post/7000556808863481886

一) 枚举部分的: 递归枚举

https://www.w3xue.com/exp/article/20204/83930.html

//递归枚举值实例
enum Expression{
    //单个数值
    case num(param:Int)
    //表示加法运算 将Expression作为相关值参数类型
    indirect case add(param:Expression,param2:Expression)
    //表示减法运算 将Expression作为相关值参数类型
    indirect case sub(param:Expression,param2:Expression)
    //表示乘法运算 将Expression作为相关值参数类型
    indirect case mul(param:Expression,param2:Expression)
    //表示除法运算 将Expression作为相关值参数类型
    indirect case div(param:Expression,param2:Expression)
}
//使用递归枚举实现((4+4)*2-8)/2的复合表达式
//创建单值4
var num = Expression.num(param: 4)
//进行4+4运算
var num4Add4 = Expression.add(param: num, param2: num)
var num2 = Expression.num(param: 2)
//进行(4+4)*2
var numMul2 = Expression.mul(param: num4Add4, param2: num2)
var num3 = Expression.num(param: 8)
//进行(4+4)*2-8
var numSub8 = Expression.sub(param: numMul2, param2: num3)
var num4 = Expression.num(param: 2)
//进行((4+4)*2-8)/2
var numDiv = Expression.div(param: numSub8, param2: num4)
 
//定义功能方法
func expressionFunc(param:Expression)->Int{
    switch param {
    case let .num(param: val):
        return val
    case let .add(param: val1, param2: val2):
        return expressionFunc(param: val1)+expressionFunc(param: val2)
    case let .mul(param: val1, param2: val2):
        return expressionFunc(param: val1)*expressionFunc(param: val2)
    case let .sub(param: val1, param2: val2):
        return expressionFunc(param: val1)-expressionFunc(param: val2)
    case let .div(param: val1, param2: val2):
        return expressionFunc(param: val1)/expressionFunc(param: val2)
    }
}
//方法调用
print(expressionFunc(param: numDiv))

二) 结构体和类对比

Swift 中结构体和类有很多共同点。两者都可以:

  • 定义属性用于存储值

  • 定义方法用于提供功能

  • 定义下标操作用于通过下标语法访问它们的值

  • 定义构造器用于设置初始值

  • 通过扩展以增加默认实现之外的功能

  • 遵循协议以提供某种标准功能

更多信息请参见 属性方法下标构造过程扩展协议

与结构体相比,类还有如下的附加功能:

  • 继承允许一个类继承另一个类的特征

  • 类型转换允许在运行时检查和解释一个类实例的类型

  • 析构器允许一个类实例释放任何其所被分配的资源

  • 引用计数允许对一个类的多次引用

三) @IBDesignable和@IBInspectable

https://blog.csdn.net/tounaobun/article/details/39890667
说,可以将自定义的代码实时渲染到Interface Builder中。而它们之间的桥梁就是通过两个指令来完成,即@IBDesignable和@IBInspectable。我们通过@IBDesignable告诉Interface Builder这个类可以实时渲染到界面中,但是这个类必须是UIView或者NSView的子类。通过@IBInspectable可以定义动态属性,即可在attribute inspector面板中可视化修改属性值。

使用方法:在swift里,@IBDesignable关键字写在class前即可。
在OC里,是IB_DESIGNABLE这个关键字,写在@implementation前即可
IBInspectable
主要作用:使view内的变量可视化,并且可以修改后马上看到

使用方法:在swift里,@IBInspectable关键字写在需要显示的变量前即可
在OC里,是IBInspectable这个关键字,写在需要显示的变量前即可
另外附两个快捷键:
command+shift+O,快速打开需要的文件
control+shift+鼠标左击sb,可以选择需要的sb活着view

四) 闭包 相关

闭包


{ (parameters) -> return type in
    statements
}

  weatherService.retrieveWeatherInfo(location) { (weather, error) -> Void in
      DispatchQueue.main.async(execute: {
        if let unwrappedError = error {
          print(unwrappedError)
          self.update(unwrappedError)
          return
        }

        guard let unwrappedWeather = weather else {
          return
        }
        self.update(unwrappedWeather)
      })
    }

关键词:in

viewModel?.location.observe {
            [unowned self] in
            self.locationLabel.text = $0
            
            let attributeSet = CSSearchableItemAttributeSet(itemContentType: kUTTypeText as String)
            attributeSet.title = self.locationLabel.text
            
            let item = CSSearchableItem(uniqueIdentifier: self.identifier, domainIdentifier: "com.rushjet.SwiftWeather", attributeSet: attributeSet)
            CSSearchableIndex.default().indexSearchableItems([item]){error in
                if let error =  error {
                    print("Indexing error: \(error.localizedDescription)")
                } else {
                    print("Location item successfully indexed")
                }
            }
        }

五) 泛型相关

class Observable<T> {
  typealias Observer = (T) -> Void
  var observer: Observer?

  func observe(_ observer: Observer?) {
    self.observer = observer
    observer?(value)
  }

  var value: T {
    didSet {
      observer?(value)
    }
  }

  init(_ value: T) {
    self.value = value
  }
}

六) fileprivate

private 表示代码只能在当前作用域或者同一文件中同一类型的作用域中被使用,
fileprivate 表示代码可以在当前文件中被访问,而不做类型限定。

https://blog.csdn.net/a18339063397/article/details/87862081

一个当前文件可用, 一个当前的文件不可用

//ViewController.swift
class Person: NSObject {
 
    fileprivate var name:String = "man"
    
    private var age:Int = 1
}
 
class ViewController: UIViewController {
 
    override func viewDidLoad() {
        super.viewDidLoad()
    
        let p = Person()
        print(p.name)
        
        //编译器不会提示age属性 如果强行写p.age
        //会报错'age' is inaccessible due to 'private' protection level
        //print(p.age)
    }
}
log:  man
//ViewController.swift
extension Person {
    
    func printAge()  {
        print(self.age)
        //在 当前文件的 extension 中,调用private 修饰的属性没问题
    }
    
    func prinName()  {
      //在 当前文件的 extension 中,调用fileprivate 修饰的属性没问题
        print(self.name)
    }
}
 
    override func viewDidLoad() {
        super.viewDidLoad()
    
        let p = Person()        
        p.printAge()
        p.prinName()
    }

七) QuickSpec 写单元测试

qucik 写单元测试
https://juejin.cn/post/6844903510870327303

八) qucik 写 UItest

九 @objc

Objective-C 对象是基于运行时的,方法或属性使用动态派发 ,在运行调用时再决定实际调用的具体实现。而 Swift 为了追求性能,如果没有特殊需要的话,是不会在运行时再来决定这些的。也就是说,Swift 类型的成员或者方法在编译时就已经决定,而运行时便不再需要经过一次查找,而可以直接使用。

Objective-C 中所有类都继承自NSObject,Swift 中的类如果要供 Objective-C 调用,必须也继承自NSObject。

十 . 若扩展名前加@noobjc,则该扩展的所有方法都不会隐式添加@objc(排除类名前加@objcMembers的影响);

swift json 的语法解析:

public enum SwiftyJSONError: Int, Swift.Error {
   case unsupportedType = 999
   case indexOutOfBounds = 900
   case elementTooDeep = 902
   case wrongType = 901
   case notExist = 500
   case invalidJSON = 490
}

Swift.Error 是一种协议 。

extension SwiftyJSONError: CustomNSError {

扩展遵守协议

  public var errorCode: Int { return self.rawValue }
  public init(data: Data, options opt: JSONSerialization.ReadingOptions = []) throws {
        let object: Any = try JSONSerialization.jsonObject(with: data, options: opt)
        self.init(jsonObject: object)
    }

   public mutating func merge(with other: JSON) throws {
        try self.merge(with: other, typecheck: true)
    }

    /// JSON type, fileprivate setter
    public fileprivate(set) var type: Type = .null
 public subscript(path: JSONSubscriptType...) -> JSON {
        get {
            return self[path]
        }
        set {
            self[path] = newValue
        }
    }

一个叫做 path 的 JSONSubscriptType... 型可变参数,在函数体内可以当做一个叫 path 的 [JSONSubscriptType] 型的数组常量。

            case .key(let key):     self[key: key] = newValue
   public enum JSONKey {
    case index(Int)
    case key(String)
}

    func encode<Parameters: Encodable>(_ parameters: Parameters?, into request: URLRequest) throws -> URLRequest

为了表示一个函数、方法或构造器可以抛出错误,在函数声明的参数之后加上 throws 关键字。一个标有 throws 关键字的函数被称作 throwing 函数。如果这个函数指明了返回值类型,throws 关键词需要写在返回箭头(->)的前面。

func canThrowErrors() throws -> String

func cannotThrowErrors() -> String

只读计算属性的声明可以去掉 get 关键字和花括号:

struct Cuboid {
   var width = 0.0, height = 0.0, depth = 0.0
   var volume: Double {
       return width * height * depth
   }
}

如果一个函数的整个函数体是一个单行表达式,这个函数可以隐式地返回这个表达式。举个例子,以下的函数有着同样的作用:

public static func userAgent(_ value: String) -> HTTPHeader {
        HTTPHeader(name: "User-Agent", value: value)
    }

swift的 static
总结

 static能修饰class/struct/enum的计算属性、存储属性、类型方法;class能修饰类的计算属性和类方法
 static修饰的类方法不能继承;class修饰的类方法可以继承
 在protocol中要使用static
func tryMapError<NewFailure: Error>(_ transform: (Failure) throws -> NewFailure) -> Result<Success, Error> {
     switch self {
     case let .failure(error):
         do {
             return try .failure(transform(error))
         } catch {
             return .failure(error)
         }
     case let .success(value):
         return .success(value)
     }
 }

NewFailure: Error 是泛型的约束

image.png
image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容