观察UIView更改崩溃

我已经使用下面的代码来确定视图何时被添加到超级视图:

//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位 ,我得到

originalImp(_self,@selector(willMoveToSuperview :),superview)上的EXC_BAD_ACCESS(code = EXC_I386_GPFLT);

任何人有任何见解?

谢谢

这似乎是在imp_implementationWithBlock上使用imp_implementationWithBlock崩溃。

你可以尝试使用经典的swizzling(把代码放在你的块中的swizzledWillMoveToSuperview:方法中,交换两个方法/select器的实现,然后在swizzledWillModeToSuperview:调用[self swizzledWillModeToSuperview:superview] swizzledWillModeToSuperview: [self swizzledWillModeToSuperview:superview] swizzledWillModeToSuperview:实际调用原始实现)。

避免使用imp_implementationWithBlock并使用现有方法的实现反而似乎适用于32位和64位体系结构。

请注意,这不会覆盖所有的情况,特别是如果有人在不调用super类的情况下willMoveToSuperview类UIView进行重写,并且重写willMoveToSuperview ,那么这些实现将不会像您期望的那样被debugging,并且对这些观察不起作用。