我想在我的项目中的UIViewController的每个子类中以deinit记录一些语句。我不想在每个视图控制器子类中复制/粘贴相同的行。
答案 0 :(得分:3)
有一种方法可以达到这个目的。
你无法调动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
被解除分配。
答案 1 :(得分:0)
我更新了间接调用swift代码的解决方案,可能不是最好的方法。您可以使用NSSelectorFromString
获得取消初始化的实现,并通过扩展扩展实现,并通过桥接调用快速代码。尝试使用此代码可能会帮助您:
//
// 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
快捷代码:
import Foundation
import UIKit
class CustomBehaviorHandler:NSObject {
@objc
static func printMe() {
print("deinitializing ....")
}
}
[已更新]