我使用下面的代码来确定何时将 View 添加到父 View :
//Makes views announce their change of superviews
Method method = class_getInstanceMethod([UIView class], @selector(willMoveToSuperview:));
IMP originalImp = method_getImplementation(method);
void (^ block)(id, UIView *) = ^(id _self, UIView *superview) {
[_self willChangeValueForKey:@"superview"];
originalImp(_self, @selector(willMoveToSuperview:), superview);
[_self didChangeValueForKey:@"superview"];
};
IMP newImp = imp_implementationWithBlock((__bridge id)((__bridge void*)block));
method_setImplementation(method, newImp);
我对此没有任何问题,但是当我尝试在 64 位 中运行它时,我得到了
EXC_BAD_ACCESS (code=EXC_I386_GPFLT) on originalImp(_self, @selector(willMoveToSuperview:), superview);
谁有什么见解?
谢谢
最佳答案
似乎在 arm64 上使用 imp_implementationWithBlock
会崩溃。
您可以尝试使用经典的 swizzling(将代码放在专用的 swizzledWillMoveToSuperview:
方法中,交换两种方法/选择器的实现,然后调用 [self swizzledWillModeToSuperview:superview]
在 swizzledWillModeToSuperview:
中实际调用原始实现)。
避免使用 imp_implementationWithBlock
并使用现有方法的实现似乎适用于 32 位和 64 位架构。
请注意,无论如何这不会涵盖所有情况,尤其是如果有人子类化 UIView 并覆盖 willMoveToSuperview
而不调用 super
,那么这些实现将不会正如您所期望的那样 swizzled 并且对这些的观察将不起作用。
关于ios - 观察 UIView 变化崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22567869/