我想在我的项目中 UIViewController 的每个子类中的 deinit 中记录一些语句。我不想在每个视图控制器子类中复制/粘贴相同的行。
问问题
1126 次
2 回答
8
有一种方法可以实现这一点。
你不能调配deinit
,但你可以调配另一种方法,比如viewDidLoad
用associatedObject
. 当 viewController 解除分配时,关联对象也被解除分配。
final class Deallocator {
var closure: () -> Void
init(_ closure: @escaping () -> Void) {
self.closure = closure
}
deinit {
closure()
}
}
private var associatedObjectAddr = ""
extension UIViewController {
@objc fileprivate func swizzled_viewDidLoad() {
let deallocator = Deallocator { print("Deallocated") }
objc_setAssociatedObject(self, &associatedObjectAddr, deallocator, .OBJC_ASSOCIATION_RETAIN)
swizzled_viewDidLoad()
}
static let classInit: Void = {
let originalSelector = #selector(viewDidLoad)
let swizzledSelector = #selector(swizzled_viewDidLoad)
let forClass: AnyClass = UIViewController.self
let originalMethod = class_getInstanceMethod(forClass, originalSelector)
let swizzledMethod = class_getInstanceMethod(forClass, swizzledSelector)
method_exchangeImplementations(originalMethod!, swizzledMethod!)
}()
}
警告
当 viewController 被释放时,闭包不会被准确地调用,因为在viewController 完全释放Deallocator
后才被释放。
于 2018-06-13T11:54:11.877 回答
0
我更新了间接调用swift代码的解决方案,可能不是最好的。NSSelectorFromString
您可以使用swizzling 和扩展实现来获得 de-init 实现,并通过桥接调用 swift 代码。试试这个可能对你有帮助的代码:
//
// UIViewController+ExtendDealloc.h
// extension
//
// Created by Amir Kamali on 26/2/19.
// Copyright © 2019 Amir Kamali. All rights reserved.
//
@import UIKit;
@interface UIViewController (ExtendDealloc)
@end
.m 文件:
//
// UIViewController+ExtendDealloc.m
// extension
//
// Created by Amir Kamali on 26/2/19.
// Copyright © 2019 Amir Kamali. All rights reserved.
//
#import "UIViewController+ExtendDealloc.h"
#import <objc/runtime.h>
#import "test_objc-Swift.h"
@implementation UIViewController (ExtendDealloc)
#pragma mark - Swizzle Dealloc
+ (void)load {
// is this the best solution?
method_exchangeImplementations(class_getInstanceMethod(self.class, NSSelectorFromString(@"dealloc")),
class_getInstanceMethod(self.class, @selector(swizzledDealloc)));
}
- (void)swizzledDealloc {
[CustomBehaviorHandler printMe];
[self swizzledDealloc];
}
@end
SWIFT代码:
import Foundation
import UIKit
class CustomBehaviorHandler:NSObject {
@objc
static func printMe() {
print("deinitializing ....")
}
}
[更新]
于 2019-02-26T04:53:04.437 回答