swift方法交换 - CSDN
精华内容
参与话题
  • //1 swap(&arr[fromIndexPath.row], &arr[to.row]) //2 (arr[fromIndexPath.row],arr[to.row]) = (arr[to.row],arr[fromIndexPath.row]) 转载于:https://www.cnblogs.com/ficow/p/5777...

     

     

     

     

    //1
    swap(&arr[fromIndexPath.row], &arr[to.row])
    
    //2
    (arr[fromIndexPath.row],arr[to.row]) = (arr[to.row],arr[fromIndexPath.row])

     

    转载于:https://www.cnblogs.com/ficow/p/5777395.html

    展开全文
  • 主要给大家介绍了关于swift中利用runtime交换方法的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
  • 利用AOP的思想,通过方法交换(Method Swizzle黑魔法,修改 ios 系统类库方法)的做法,对登陆权限的统一管理,避免判断逻辑的分散。可以举一反三,思考类似需求的处理方案
  • Swift5 Method Swizzling 方法交换

    千次阅读 2020-09-10 10:12:01
    最近看了一下关于Swift5的特性,发现了一个叫 @_...然后输入以下代码,这里有一个key word叫dynamic,这个关键字在Swift3中就出现了,代表动态派发,只有加了dynamic修饰的方法才能被@_dynamicReplacement(fo...

    最近看了一下关于Swift5的特性,发现了一个叫 @_dynamicReplacement(for:) 的新特性比较有趣,所以研究了一下。
    新建一个Swift 5.0的工程,然后输入以下代码,这里有一个key word叫dynamic,这个关键字在Swift3中就出现了,代表动态派发,只有加了dynamic修饰的方法才能被@_dynamicReplacement(for:) :

    import Foundation
    
    class Test {
        dynamic func testA() {
            print("testA")
        }
    }
    
    extension Test {
        @_dynamicReplacement(for: testA())
        func testB() {
            print("testB")
        }
    }
    
    Test().testA()
    

    运行一下发现控制台输出了:

    testB
    Program ended with exit code: 0
    

    与OC的Method Swizzling做一个比较:
    先写一个OC的类:

    //Test.h
    #import <Foundation/Foundation.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface Test : NSObject
    - (void)testA;
    - (void)testB;
    - (void)testC;
    @end
    
    NS_ASSUME_NONNULL_END
    
    //Test.m
    #import "Test.h"
    #import <objc/runtime.h>
    
    @implementation Test
    
    + (void)load {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            Class class = [self class];
            SEL testASelector = @selector(testA);
            SEL testBSelector = @selector(testB);
            Method testAMethod = class_getInstanceMethod(class, testASelector);
            Method testBMethod = class_getInstanceMethod(class, testBSelector);
            method_exchangeImplementations(testAMethod, testBMethod);
    
            SEL testCSelector = @selector(testC);
            Method testCMethod = class_getInstanceMethod(class, testCSelector);
            method_exchangeImplementations(testAMethod, testCMethod);
        });
    }
    
    - (void)testA {
        NSLog(@"A");
    }
    
    - (void)testB {
        NSLog(@"B");
        [self testB];
    }
    
    - (void)testC {
        NSLog(@"C");
        [self testC];
    }
    @end
    
    //main.m
    #import <Foundation/Foundation.h>
    #import "Test.h"
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            Test * t = [[Test alloc] init];
            [t testA];
        }
        return 0;
    }
    

    上面的程序很明显,运行结果是:

    2019-09-26 23:12:39.513796+0800 OC[87404:218117] C
    2019-09-26 23:12:39.514014+0800 OC[87404:218117] B
    2019-09-26 23:12:39.514036+0800 OC[87404:218117] A
    Program ended with exit code: 0
    

    OC中方法交换是一个一个来的,所以结果会输出 CBA,因为 testA 方法首先被替换成了 testB ,其替换后的结果又被替换成了 testC 。进而由于 Swizze 的方法都调用了原方法,所以会输出 CBA。

    Method Swizzling 在 Runtime 中的原理就是方法指针的交换。
    由于 OC 对于实例方法的存储方式是以方法实例表,那么我们只要能够访问到其指定的方法实例,修改 imp 指针对应的指向,再对引用计数和内存开辟等于 Class 相关的信息做一次更新就实现了 Method Swizzling。

    对于这个例子,我们用Swift的@_dynamicReplacement(for:) 写一遍:

    import Foundation
    
    class Test {
        dynamic func testA() {
            print("A")
        }
    }
    
    extension Test {
        @_dynamicReplacement(for: testA())
        func testB() {
            print("B")
            testA()
        }
    }
    
    extension Test {
        @_dynamicReplacement(for: testA())
        func testC() {
            print("C")
            testA()
        }
    }
    
    Test().testA()
    

    跑一下代码,发现运行结果却是:

    C
    A
    Program ended with exit code: 0
    

    交换一下两个 extension 的顺序继续尝试,其打印结果又变成了 BA 。

    所以可以断定在执行顺序上,后声明的将会生效。

    那么应该如何实现这种连环 Hook 的场景呢?

    经过多次的尝试,从代码层面应该是不可能办到了,总会以最后一次的方法为准。

    因此在Build Settings 中 的Other Swift Flags 里增加 -Xfrontend -enable-dynamic-replacement-chaining :
    在这里插入图片描述
    重新运行一遍,奇迹发生了:
    在这里插入图片描述

    展开全文
  • Swift:函数与方法

    千次阅读 2018-03-10 22:35:58
    在介绍Swift中的函数与方法之前,我们先看看objective-c中函数与方法的写法,以求两个数的和为例:1. 函数写法int sum(int a, int b) { return a + b; }2. 方法写法- (int)sum:(int)a b:(int)b { retur...

    本人录制技术视频地址:https://edu.csdn.net/lecturer/1899 欢迎观看。

    在介绍Swift中的函数与方法之前,我们先看看objective-c中函数与方法的写法,以求两个数的和为例:

    1. 函数写法

    int sum(int a, int b) {
        return a + b;
    }

    2. 方法写法

    - (int)sum:(int)a b:(int)b {
        return a + b;
    }

    从上面可以看出,两者的写法还是有很大不同的。而到了Swift中,直接将两者进行了统一,写法如下:

    func sum(a: Int, b: Int) -> Int {
        return a + b;
    }

    因为两者进行了统一,所以下面的描述,我统一的称之为方法。


    一、方法的定义格式

    func 方法名(参数名称: 参数类型, ....) -> 返回值类型 {

    }


    二、方法的几种形态

    1. 没有返回值的方法

    func test(num1: Int) -> Void{
        
    }

    或者

    func test(num1: Int) -> (){
        
    }

    或者

    func test(num1: Int){
    
    }

    2. 没有形式参数的方法

    func test() -> Int{
        return 0
    }

    3. 返回多个值的方法,即返回元组形式

    func find(id: Int) -> (name: String, age: Int) {
        if id > 0 {
            return ("Jack", 20)
        } else {
            return ("Rose", 18)
        }
    }
    
    var person = find(2)
    println("name=\(person.name)", age=\(person.age))

    4. 可变参数列表(借鉴了C#中的params)

    func sumOf(numbers: Int...) -> Int {
        var sum = 0
        for number in numbers {
            sum += number
        }
        
        return sum
    }
    
    //sumOf()  		结果为:0
    //sumOf(1,2,3,4)	结果为:10

    三、 形参的类型

    1. 外部参数名(在形式参数前面再定义一个名称,这样调用方法的时候就有名称提示了)

    func test(number1 num1:Int,number2 num2:Int) -> Int{
        return num1 + num2
    }
    
    test(number1: 3, number2: 5)

    注意到,在参数num1和num2前面分别添加了名称number1和number2,这样在调用方法test的时候,系统会自动提示你将要输入的参数的提示名称。


    2. 提示名称与形式参数名称一致,在形式参数前面加上#

    func test(#num1:Int, #num2:Int) -> Int{
        return num1 + num2
    }
    
    test(num1: 3, num2: 6)


    3. 默认参数值(即方法中的某个参数有默认值)

    func addStudent(name: String, age: Int = 20){
        println("添加学生:name=\(name), age=\(age)")
    }

    从上面的例子可以看出,age这个形式参数有一个默认参数值20. 它的意思是,你调用方法的时候,如果传入age的值,则将覆盖掉20这个值;如果只传入name的值,则age的值就为20.

    调用结果如下:

    addStudent("Lifei")        // 添加学生:name=Lifei, age=20
    
    addStudent("Jack", age: 30)  // 添加学生:name=Jack, age=30

    从上面的调用形式可以看出,默认参数值的参数是外部参数名的形式,因为它出现了age这个提示语。


    4. Swift中默认的方法形式参数是常量参数,不能修改

    func test(num1: Int){
    
    }

    相当于

    func test(let num1: Int){
    
    }

    如果想要参数是变量参数,需手动在形式参数名称加上var关键字,例如

    func append(var destStr: String, sourceStr: String, num: Int) -> String{
        for _ in 0..<num{
            destStr += sourceStr
        }
        return destStr
    }
    
    var result = append("Lifei", "@", 6)

    在变量destStr前面加了var修饰,这样在方法内部就可以使用destStr进行运算等操作了。


    5. 输入输出参数,用inout关键字修饰

    func change(inout num1: Int){
        num1 = 10
    }
    
    var a = 20
    change(&a)
    a
    其实,它的原理就是传递的变量的地址,而不是值。再举个例子,就是交换两个数的值。

    func exchange(inout num1: Int,inout num2: Int){
        var temp = num1;
        num1 = num2;
        num2 = temp;
    }
    
    var a = 10
    var b = 20
    exchange(&a, &b)

    四、方法类型

    Swift中的方法类型也是数据类型的一种,例如:

    func test(num1:Int, num2:Int) -> Int{
        return num1 + num2
    }

    这个方法的类型就是

    (Int, Int) -> Int

    可以利用方法类型来定义变量(fn这个变量的类型就是test的方法类型)

    var fn:(Int, Int) -> Int = test
    fn(10,20)

    方法做为类型使用举例1:

    func add(num1: Int,num2: Int) ->Int{
        return num1 + num2
    }
    
    func minus(num1: Int,num2: Int) ->Int{
        return num1 - num2
    }
    
    func divide(num1: Int,num2: Int) ->Int{
        return num1 / num2
    }
    
    
    func calcResult(fn: (Int,Int)->Int, num1: Int, num2: Int) -> Int{
        return fn(num1 , num2)
    }
    
    var addResult = calcResult(add, 10, 20)
    
    var minusResult = calcResult(minus, 10, 20)
    
    var divideResult = calcResult(divide, 100, 5)

    可以看出,方法calcResult中的一个参数的类型就是(Int, Int) -> Int, 然后在调用的时候,就非常的方便了。


    方法做为类型使用举例2:

    func goToWork(){
        println("上班去")
    }
    
    func haveFun(){
        println("休息一下")
    }
    
    func howToDo(day: Int) -> Void -> Void{
        if(day == 6 || day == 7){
            return haveFun
        }else{
            return goToWork
        }
    }
    
    var fn = howToDo(1)
    fn()

    展开全文
  • swift4 交换方法

    2019-06-16 22:34:10
    2019独角兽企业重金招聘Python工程师标准>>> ...

    你可以已经网上找了一些方法发现
    1:initialize swift4已经无法重写

    //
    //  ViewController.swift
    //  TestOnce
    //
    //  Created by point on 2018/5/22.
    //  Copyright © 2018年 whiteboard. All rights reserved.
    //
    
    import UIKit
    //
    extension UIViewController {
        public  class func myOnceMethod() {
            DispatchQueue.once(token: "ddddddd") {
                let originalSelector = Selector.sysP
                let swizzledSelector = Selector.sysP2
                changeMethod(originalSelector, swizzledSelector, self)
            }
        }
        
        
        static func changeMethod(_ original:Selector,_ swizzled:Selector,_ object: AnyClass) -> () {
            
            let originalMethod = class_getInstanceMethod(object, original)
            let swizzledMethod = class_getInstanceMethod(object, swizzled)
            
            let didAddMethod: Bool = class_addMethod(object, original, method_getImplementation(swizzledMethod!), method_getTypeEncoding(swizzledMethod!))
            if didAddMethod {
                class_replaceMethod(object, swizzled, method_getImplementation(originalMethod!), method_getTypeEncoding(originalMethod!))
            } else {
                method_exchangeImplementations(originalMethod!, swizzledMethod!)
            }
        }
        
        
        
        
        @objc func DCPresent(_ viewControllerToPresent: UIViewController, animated flag: Bool, completion: (() -> Swift.Void)? = nil) {
            print("sssss")
            
            DispatchQueue.main.async {
                self.DCPresent(viewControllerToPresent, animated: flag, completion: nil)
            }
        }
    }
    
    fileprivate extension Selector {
        //    static let viewWillAppear = #selector(UIViewController.viewWillAppear(_:))
        //    static let yz_viewWillAppear = #selector(UIViewController.yz_viewWillAppear(animated:))
        
        
        static let sysP = #selector(UIViewController.present(_:animated:completion:))
        static let sysP2 = #selector(UIViewController.DCPresent(_:animated:completion:))
    }
    
    
    
    class ViewController: UIViewController {
        
        
        
        
        override func viewDidLoad() {
            super.viewDidLoad()
            
        }
        
        override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
            self.present(SBViewController(), animated: true, completion: nil)
            
        }
    }
    
    
    extension DispatchQueue {
        private static var onceTracker = [String]()
        
        open class func once(token: String, block:() -> Void) {
            objc_sync_enter(self)
            defer { objc_sync_exit(self) }
            
            if onceTracker.contains(token) {
                return
            }
            onceTracker.append(token)
            block()
        }
    }
    
    

     

     func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
            UIViewController.myOnceMethod()
            // Override point for customization after application launch.
            return true
        }

     

    转载于:https://my.oschina.net/zhaodacai/blog/1816617

    展开全文
  • Swift - 交换数组中两个元素位置

    千次阅读 2017-09-11 11:55:19
    交换数组中两个元素位置方法一:苹果提供的swap方法代码var originArrayOne = [2,3,4] print("originArrayOne排序前:\(originArrayOne)") //交换第0个元素和第2个元素位置 //方法一 swap(&originArrayOne[0], &...
  • Swift 中使用runtime交换方法实现

    千次阅读 2016-08-13 17:13:33
    swift的ViewController中写了如下代码:  func first () {  print("第一个方法")  }  func second () {  print("第second个方法")  }  override func viewDidLoad() {  super.viewDidLoad()
  • 31、swift开发iOS——泛型

    万次阅读 2017-03-12 23:23:33
    Swift 泛型 Swift 提供了泛型让你写出灵活且可重用的函数和类型。 Swift 标准库是通过泛型代码构建出来的。 Swift 的数组和字典类型都是泛型集。 你可以创建一个Int数组,也可创建一个String数组,或者甚至于...
  • Swift WKWebView的js调用swift

    千次阅读 2017-03-13 18:01:48
    最近项目需求,需要用到JavaScriptCore和WebKit,但是网上的资源有限,而且比较杂,都是一个博客复制...js调用swift controller的代码: import UIKit import WebKit class JSCallSwiftController: UIViewController {
  • 升级Swift4.0遇到的坑

    万次阅读 2017-09-12 19:36:19
    升级Swift4.0 并不是所有库都能做到及时支持Swift4.0,更何况是在现在连Xcode9也还是beta的状态 所以我们仅能做到将自己的业务代码(主工程代码)部分升级到Swift4.0,然后同时保留各种pod库在Swift3.2版本。 没...
  • 数组元素交换 swap

    千次阅读 2017-06-12 15:25:53
    swift中关键字 144 作者 夜晚看日出 关注 2017.01.05 18:39* 字数 5778 阅读 120评论 0喜欢 0 一、前言swift中使用到的关键字,做个笔记,后期再使用到其它关键字再做添加二、关键字deinit 、typealias 、is 、...
  • IBAN和SWIFT代码有什么不同?

    千次阅读 2019-04-12 16:22:23
    IBAN和SWIFT是在金融机构之间传递交易的两种标准化格式。IBANs (国际银行账号)主要在欧洲使用,并识别跨国界的特定账户。SWIFT (全球银行间金融电信协会)代码识别机构。 1、专业一些的说法是BIC是银行识别码,意思...
  • 字号:大 中 小 1、SWIFT简介SWIFT 是“环球同业银行金融电讯协会”( Society for Worldwide Interbank Financial Telecommunication)的英文缩写,它是一个国际银行间非盈利的国际合作组织,总部设在比利时的...
  • Swift3.0 泛型<T>

    万次阅读 热门讨论 2017-05-25 17:58:44
    泛型能够让开发者编写自定义需求已经任意类型的灵活可用的的函数和类型。能够让我们避免重复的代码。用一种清晰和抽象的方式来表达代码的意图。 1.泛型解决的问题 下面是一个非泛型的例子 func swapTwoIntValue(in...
  • 做过OC开发的都知道,我们想要给一个系统的类添加一个属性我们有几种方法,比如继承,我们创建一个父类,给父类写一个属性,之后所有使用的类都采用继承该父类的方式,这样就会都拥有该属性.更高级一点的我们会用到OC的...
  • Swift 泛型函数 类型约束(十三)

    千次阅读 2016-06-12 09:55:45
    非泛型函数/// 交换两个整形的值 func swapTwoNumbersInt(inout a: Int, inout _ b:Int) { let temp = a a = b b = temp }/// 交换两个字符串的值 func swapTwoString(inout string1: String, inou
  • 之前通过几篇文章介绍了现代化支付系统行号CNAPS Code、...而在国际业务,涉及境外外资银行之间的报文传递,人民银行制定的编码规范显然是无法满足需求的,这就引出了SWIFT—Society for Worldwide Interbank Financ
  • iOS ScrollView嵌套ScrolloView解决方案 - Swift

    万次阅读 热门讨论 2018-05-12 21:38:27
    iOS ScrollView嵌套ScrolloView解决方案 - Swift本文Demo下载地址:ScrollView嵌套ScrolloView解决方案(初级、进阶)1. 基础版实现思路1.1:层次结构底部是一个UITableView,上面黄色部分为tableView的...
  • swift_重载和自定义运算符

    千次阅读 2014-09-12 09:21:12
    像这样定义一个结构体 struct Vector2D {  var x = 0.0  var y = 0.0 } 当 Vector2D 的两个变量相加时,我们需要这样做: let v1 = Vector2D(x: 2.0, y: 3.0) let v2 = Vector2D(x: 4.0, y: 5.0) ...
1 2 3 4 5 ... 20
收藏数 6,054
精华内容 2,421
热门标签
关键字:

swift方法交换