澳门威利斯人_威利斯人娱乐「手机版」

来自 澳门威利斯人 2020-04-10 07:16 的文章
当前位置: 澳门威利斯人 > 澳门威利斯人 > 正文

威尼斯人网上赌场Swift和Objective-C运行时

正文翻译自斯维夫特 & the Objective-C Runtime 翻译的卓殊的地点还请多多原谅指正,多谢~

纵然不写一行OC(Objective-C)代码,每一种Swfit应用如故施行在OC运营时内部,展开三个动态调整的世界和有关的运维时操作。的确,项目只用斯威夫特框架的景况不一连存在,但只要这种状态惠临,大概就能够现出运维时内只存在Swift而从不OC。只要OC运营时平昔留存,大家就该表述它的全套潜在的力量

即使一行 Objective-C 代码也不写,每一个 Swift app 都会在 Objective-C runtime 中运转,开运行态任务分发和平运动作时对象关系的社会风气。更适于地说,恐怕在仅使用 Swift 库的时候只运营 斯维夫特 runtime。但 Objective-C runtime 与大家共处了这么长的光阴,我们也应该将其表达到十二万分。

纵使不写一行OC(Objective-C)代码,每一种Swfit应用依旧实行在OC运营时内部,展开二个动态调节的社会风气和有关的运行时操作。的确,项目只用Swift框架的景色不总是存在,但一旦这种场馆降临,可能就能够现身运转时内只设有斯威夫特而还未OC。只要OC运转时一向存在,我们就该表述它的整个潜能。

涉嫌对象(Associated Objects)

本周的 NShipster 大家将以 Swift视角来观望那七个运维时中有关关联对象(associated objects卡塔尔(قطر‎和办法陆陆续续(method swizzling卡塔尔的技能。

我们将利用一种新的,侧重于Swift的角度省视多少个运营时本事:关联对象及函数置换,NSHipster在付出历史唯有OC语言的时候对那二种技巧原来就有介绍。

Swift扩充对于在存活Cocoa类中增加效果函数有大幅度地灵活性,但就像斯维夫特同胞OC的档案的次序(category)同样,扩充是有限定的。也正是说,通过扩张也无法对现成的类加多属性。

论及对象(Associated Objects卡塔尔(قطر‎

斯威夫特 extension 能对已经存在 Cocoa 类中增添极为丰盛的效应,但它的兄弟 Objective-C 的 category 却不及了多数。比方说 Objective-C 中的 extension 就不能向既有类增加属性。

令人庆幸的是 Objective-C 的 关联对象 能够减轻这种局面。例如要向二个工程里有所的 view controllers 中加多一个descriptiveName 属性,我们得以简轻松单的运用 objc_get/setAssociatedObject(卡塔尔来填充其 get 和 set 块:
<pre><code>
extension UIViewController {
private struct AssociatedKeys {
static var DescriptiveName = "nsh_DescriptiveName"
}

var descriptiveName: String? {
    get {
        return objc_getAssociatedObject(self, &AssociatedKeys.DescriptiveName) as? String
    }
    set {
        if let newValue = newValue {
            objc_setAssociatedObject(
                self,
                &AssociatedKeys.DescriptiveName,
                newValue as NSString?,
                UInt(OBJC_ASSOCIATION_RETAIN_NONATOMIC)
            )
        }
    }
}

}
</code></pre>

注:文章主要涉及二种本领在斯维夫特的施用,如想详细询问请点击上述链接。

//让人欣尉的是,OC关联对象可完成对现成类增加属性。譬喻,为了在工程内对具有View Controllers加多名叫descriptiveName属性,大家只需简单地在性质的get及set方法中运用objc_get/setAssociatedObject(State of Qatar方法增添属性。
extension UIViewController {
private struct AssociatedKeys {
static var DescriptiveName = "nsh_DescriptiveName"
}

小心,在民用嵌套 struct 中采纳 static var,那样会调换我们所需的涉及对象键,但不会污染整个命名空间。

Swift扩充对于在现存Cocoa类中增加效果函数有大幅地灵活性,但就如斯维夫特同胞OC的类型(category)相近,扩大是有限量的。相当于说,通过增加也无法对现成的类增加属性。

var descriptiveName: String? {
    get {
        return objc_getAssociatedObject(self, &AssociatedKeys.DescriptiveName) as? String
    }

    set {
        if let newValue = newValue {
            objc_setAssociatedObject(
                self,
                &AssociatedKeys.DescriptiveName,
                newValue as NSString?,
                .OBJC_ASSOCIATION_RETAIN_NONATOMIC
            )
        }
    }
}

办法时断时续(Method Swizzling卡塔尔(قطر‎

偶尔为了便于,也可以有相当的大希望是缓慢解决有个别框架内的 bug,或然别无她法时,需求修正一个业已存在类的不二秘诀的表现。方法陆陆续续能够令你交流八个法子的落实,约等于是用你写的方法来重载原有办法,而且还是能够够是原有办法的作为保全不改变。

以那件事例中大家交叉 UIViewController 的 viewWillAppear 方法以打字与印刷出每贰个在荧屏上出示的 view。方法时有时无发生在 initialize 类方法调用时(如下代码所示State of Qatar;代替的兑今后 nsh_viewWillAppear 方法中:
<pre><code>
extension UIViewController {
public override class func initialize() {
struct Static {
static var token: dispatch_once_t = 0
}

    // make sure this isn't a subclass        
    if self !== UIViewController.self {
        return
    }

    dispatch_once(&Static.token) {
        let originalSelector = Selector("viewWillAppear:")
        let swizzledSelector = Selector("nsh_viewWillAppear:")

        let originalMethod = class_getInstanceMethod(self, originalSelector)
        let swizzledMethod = class_getInstanceMethod(self, swizzledSelector)

        let didAddMethod = class_addMethod(self, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))

        if didAddMethod {
            class_replaceMethod(self, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod))
        } else {
            method_exchangeImplementations(originalMethod, swizzledMethod);
        }
    }
}

// MARK: - Method Swizzling

func nsh_viewWillAppear(animated: Bool) {
    self.nsh_viewWillAppear(animated)
    if let name = self.descriptiveName {
        println("viewWillAppear: (name)")
    } else {
        println("viewWillAppear: (self)")
    }
}

}
</code></pre>

令人欣尉的是,OC关联对象可达成对现成类增多属性。比如,为了在工程内对负有View Controllers增添名字为descriptiveName天性,大家只需轻巧地在品质的getset措施中应用objc_get/setAssociatedObject()形式增多属性。

}

load vs. initialize (Swift 版本)

Objective-C runtime 理论上会在加载和最初化类的时候调用多个类方式: load and initialize。在执教 method swizzling 的初藳中 马特t 老师提出出于安全性和一致性的思谋,方法陆续进程 永世 会在 load(卡塔尔(قطر‎方法中展开。每叁个类在加载时只会调用三次 load 方法。其他方面,多少个initialize 方法能够被多个类和它兼具的子类调用,举个例子说 UIViewController 的该方式,倘诺那么些类未有被传递新闻,那么它的 initialize 方法就永久不会被调用了。

噩运的是,在 Swift 中 load 类方法长久不会被 runtime 调用,由此方法时有时无就形成了不容许的事。但我们还也许有多少个主意:

在 initialize 中落真实情状势时有时无这种做法很安全,你只要求有限接济相关的不二秘籍陆陆续续在三个 dispatch_once 中就好了(那也是最推荐的做法卡塔尔国。

在 app delegate 中贯彻方式时断时续不像上边通过类扩张进行艺术陆陆续续,而是大约地在 app delegate 的
<pre><code>application(_:didFinishLaunchingWithOptions:)
</code></pre>
格局调用时中实践有关代码也是能够的。基于对类的修正,这种艺术应该就够用确定保障那个代码会被施行到。

本文由澳门威利斯人发布于澳门威利斯人,转载请注明出处:威尼斯人网上赌场Swift和Objective-C运行时

关键词: 澳门威利斯人 iOS开发 Objective Swift swift学习