ReactiveCocoa/ReactiveCocoa — pull request #774 by rabovik (2013-08-30 16:31:33+00:00)
Title: ReactiveCocoa swizzles dealloc in such a way that brokes swizzling of any other lib in some cases.

Consider example.

1. Class **B** is inherited from **A** and does not implement `dealloc`, while **A** does.
2. **ReactiveCocoa** [adds][1] its own `dealloc` implementation to **B**, which calls original `dealloc` implementation of **A**.
3. Some other lib swizzles `dealloc` in **A** with its own implementation.
4. When an object of class **B** is deallocated only ReactiveCocoa's and original implementations are called, and lib's is not called but it should be.

```objective-c
#import "ReactiveCocoa.h"
#import
#import

@interface A : NSObject @end
@implementation A
- (void)dealloc{
NSLog(@"A");
}
@end

@interface B : A @end
@implementation B @end

static void swizzleDealloc(Class class, dispatch_block_t block) {
SEL original = NSSelectorFromString(@"dealloc");
Method method = class_getInstanceMethod(class, original);
__block void (*originalIMP)(__unsafe_unretained id, SEL) = NULL;
id newIMPBlock = ^(__unsafe_unretained id obj) {
block();
if (originalIMP) {
originalIMP(obj, original);
}else{
struct objc_super superInfo = {obj,class_getSuperclass(class)};
objc_msgSendSuper(&superInfo, original);
}
};
originalIMP = (void *)method_getImplementation(method);
originalIMP = (void *)class_replaceMethod(class,
original,
imp_implementationWithBlock(newIMPBlock),
method_getTypeEncoding(method));
}
```
```objective-c
@autoreleasepool {
id b = [B new];
[[b rac_willDeallocSignal] subscribeCompleted:^{
NSLog(@"RAC");
}];
swizzleDealloc([A class], ^{
NSLog(@"Swizzled");
});
}
// Actual log: RAC, A
// Expected log: RAC, Swizzled, A
```

rabovik@510474eb388b0489f2cf8ddf10192229c1165eec fixes this issue.

[1]: https://github.com/ReactiveCocoa/ReactiveCocoa/blob/883ef5bf0f5be580e280364e3b2a399afe67e0e7/ReactiveCocoaFramework/ReactiveCocoa/NSObject%2BRACDeallocating.m#L34-44