本文版權(quán)歸公眾號【一個(gè)老碼農(nóng)】所有娜亿。
我們說Objective-c是一門動(dòng)態(tài)語言丽已,決策會盡可能的推遲到運(yùn)行時(shí)。而Swit是一門靜態(tài)語言暇唾,也就是說Swift的對象類型促脉、調(diào)用的方法都是在編譯期就確定的,這也是為什么swift比oc性能高的原因策州。但是在Swift中所有繼承自NSObject的類瘸味,仍然保留了Objective-c的動(dòng)態(tài)性。如果想要使用它的動(dòng)態(tài)性就需要加上@objc關(guān)鍵字够挂,本篇文章就來講一下旁仿,哪些情況需要用到@objc。
1.Protocol如果是optional(非必須實(shí)現(xiàn))的孽糖,必須加上@objc
2.利用#selector調(diào)用的方法,被調(diào)用的方法須加上@objc
3.使用kvc時(shí)
4.NSPredicate篩選
5.oc與swift混合開發(fā)枯冈,swift方法/屬性需要被oc調(diào)用的,要加上@objc
6.swift的枚舉需要被oc使用的
Protocol如果是optional(非必須實(shí)現(xiàn))的办悟,必須加上@objc
如下尘奏,便是一段Swift的Protocol代碼,如果這樣寫病蛉,此Protocol中的幾個(gè)方法炫加,都必須實(shí)現(xiàn)
protocol PlayerDelegate: class {
func playerReadyToPlay(player: CustomMediaPlayer, totalTime: Double)
func playerCacheProgress(player: CustomMediaPlayer, progress: Float)
func playerPlayProgress(player: CustomMediaPlayer, currentTime: Double)
}
如果里面某些方法是非必須實(shí)現(xiàn)的瑰煎,則需要在方法前加上@objc optional,在protocol前也需要加上@objc
@objc protocol PlayerDelegate: class {
@objc optional func playerReadyToPlay(player: CustomMediaPlayer, totalTime: Double)
@objc optional func playerCacheProgress(player: CustomMediaPlayer, progress: Float)
func playerPlayProgress(player: CustomMediaPlayer, currentTime: Double)
}
利用#selector調(diào)用的方法
在Swift中#selector俗孝,相當(dāng)于oc中的@selector酒甸,而@selector會在運(yùn)行時(shí)進(jìn)行方法調(diào)用。所以在Swift中使用#selector調(diào)用方法赋铝,需要在方法前加上@objc插勤。拿button調(diào)用方法舉例:
button.addTarget(self, action: #selector(click), for: .touchUpInside)
@objc private func click() {
}
使用kvc時(shí)
kvc其實(shí)也是利用了oc的運(yùn)行時(shí)特性,所以使用kvc也需要在屬性前加上@objc革骨,如下代碼:
class People: NSObject {
@objc var name = ""
var age = 10
}
///使用valueforkey獲取name值
let people = People()
people.name = "張三"
people.age = 15
let name = people.value(forKey: "name")
print(name)
people.setValue("王麻子", forKey: "name")
使用valueforkey獲取name值农尖,或利用setvalue:forkey賦值,name前需加@objc
NSPredicate篩選
NSPredicate是利用對象屬性的key進(jìn)行篩選的屬性良哲,要加上@objc卤橄,實(shí)際上NSPredicate也是利用了對象的oc對象的kvc特性,如下代碼:
///people類
class People: NSObject {
@objc var name = ""
@objc var age = 0
}
override func viewDidLoad() {
super.viewDidLoad()
let array = NSMutableArray()
let people1 = People()
people1.name = "張三"
people1.age = 15
array.add(people1)
let people2 = People()
people2.name = "李四"
people2.age = 18
array.add(people2)
///找到age等于15的人臂外,并打印名字
let predicate = NSPredicate(format: "age == %d", 15)
if let result = array.filtered(using: predicate) as? [People], result.count > 0 {
let people = result.first
print(people?.name)
}
}
oc與swift混合開發(fā)窟扑,swift方法/屬性需要被oc調(diào)用的
oc與swift混合開發(fā),swift方法/屬性需要被oc調(diào)用的漏健,屬性或方法前需要加上@objc嚎货。
class People: NSObject {
@objc var name = ""
@objc func playGame() {
print("玩游戲")
}
}
Swift類中的屬性和方法加上@objc
People *people = [[People alloc] init];
people.name = @"111";
[people playGame];
注:類前不需要加@objc,只要是繼承自NSObject的類蔫浆,被oc調(diào)用時(shí)殖属,系統(tǒng)會默認(rèn)為被調(diào)用的類加為@objc。
oc與swift混合開發(fā)瓦盛,swift的枚舉需要被oc使用的
Swift的枚舉被oc使用時(shí)洗显,必須在enum前加上@objc,且Swift的枚舉必須是Int類型原环,否則無法被oc使用
@objc enum PeopleSex: Int {
case female = 0
case male = 1
}
Swift的枚舉挠唆,必須是Int類型,才能被oc調(diào)用
@objc與@objcMembers的區(qū)別
在Swift中嘱吗,繼承自NSObject的類如果有比較多的屬性或方法都需要加上@objc的話玄组,會多比較多的代碼。那么可以利用@objcMembers減少代碼谒麦。被@objcMembers修飾的類俄讹,會默認(rèn)為類、子類绕德、類擴(kuò)展和子類擴(kuò)展的所有屬性和方法都加上@objc患膛。當(dāng)然如果想讓某一個(gè)擴(kuò)展關(guān)閉@objc,則可以用@nonobjc進(jìn)行修飾耻蛇。
@objcMembers
class People: NSObject {
var name = ""
var age = 10
func playGame() {
print("玩游戲")
}
}
關(guān)注公眾號【一個(gè)老碼農(nóng)】免費(fèi)獲取iOS進(jìn)階學(xué)習(xí)視頻