@objc vs @objc dynamic官方解释

Some Objective-C APIs—like target-action—accept method or property names as parameters, then use those names to dynamically call or access the methods or properties. In Swift, you use the #selector and #keyPath expressions to represent those method or property names as selectors or key paths, respectively.

https://developer.apple.com/documentation/swift/using_objective-c_runtime_features_in_swift

 

一、@objc应用于函数是为了能够让函数表达为 #selector;

In Objective-C, a selector is a type that refers to the name of an Objective-C method. In Swift, Objective-C selectors are represented by the Selector structure, and you create them using the #selector expression.

import UIKit

class MyViewController: UIViewController {

    let myButton = UIButton(frame: CGRect(x: 0, y: 0, width: 100, height: 50))

    

    override init(nibName nibNameOrNil: NSNib.Name?, bundle nibBundleOrNil: Bundle?) {

        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)

        let action = #selector(MyViewController.tappedButton)

        myButton.addTarget(self, action: action, forControlEvents: .touchUpInside)

    }

    

    @objc func tappedButton(_ sender: UIButton?) {

        print("tapped button")

    }

    

    required init?(coder: NSCoder) {

        super.init(coder: coder)

    }

 

二、@objc应用于变量是为了能够让变量表达为keypath字符串,进而使用kvc功能。

class Person: NSObject {

    @objc var name: String

    @objc var friends: [Person] = []

    @objc var bestFriend: Person? = nil

    

    init(name: String) {

        self.name = name

    }

}

 

let gabrielle = Person(name: "Gabrielle")

let jim = Person(name: "Jim")

let yuanyuan = Person(name: "Yuanyuan")

gabrielle.friends = [jim, yuanyuan]

gabrielle.bestFriend = yuanyuan

 

#keyPath(Person.name)

// "name"

gabrielle.value(forKey: #keyPath(Person.name))

// "Gabrielle"

#keyPath(Person.bestFriend.name)

// "bestFriend.name"

gabrielle.value(forKeyPath: #keyPath(Person.bestFriend.name))

// "Yuanyuan"

#keyPath(Person.friends.name)

// "friends.name"

gabrielle.value(forKeyPath: #keyPath(Person.friends.name))

 

三、@objc dynamic应用于变量是为了让变量能够使用kvo机制。

class MyObjectToObserve: NSObject {

    @objc dynamic var myDate = NSDate(timeIntervalSince1970: 0) // 1970

    func updateDate() {

        myDate = myDate.addingTimeInterval(Double(2 << 30)) // Adds about 68 years.

    }

}

class MyObserver: NSObject {

    @objc var objectToObserve: MyObjectToObserve

    var observation: NSKeyValueObservation?

    

    init(object: MyObjectToObserve) {

        objectToObserve = object

        super.init()

        

        observation = observe(

            \.objectToObserve.myDate,

            options: [.old, .new]

        ) { object, change in

            print("myDate changed from: \(change.oldValue!), updated to: \(change.newValue!)")

        }

    }

}

 

let observed = MyObjectToObserve()

let observer = MyObserver(object: observed)

observed.updateDate() // Triggers the observer's change handler.

// Prints "myDate changed from: 1970-01-01 00:00:00 +0000, updated to: 2038-01-19

 

 

Here’s the least you need to remember:

  • @objc makes things visible to Objective-C code. You might need this for setting up target/action on buttons and gesture recognizers.
  • dynamic opts into dynamic dispatch. You might need this for KVO support or if you‘re doing method swizzling.
  • The only way to do dynamic dispatch currently is through the Objective-C runtime, so you must add @objc if you use dynamic.

native-objc-dynamic.png

https://www.cnblogs.com/feng9exe/p/9460336.html

posted @ 2019-03-04 18:38  zzfx  阅读(1155)  评论(0编辑  收藏  举报