performSeclector编译报可能导致内存泄漏的警告

由于消息接受者不一定有此selector,运行是可能报找不到此方法,从而崩溃。

一、宏处理忽略警告

1、忽略警告

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
    [self.ticketTarget performSelector: self.ticketAction withObject: self];
#pragma clang diagnostic pop

2、使用宏
定义宏

#define SuppressPerformSelectorLeakWarning(Stuff) \
    do { \
        _Pragma("clang diagnostic push") \
        _Pragma("clang diagnostic ignored \"-Warc-performSelector-leaks\"") \
        Stuff; \
        _Pragma("clang diagnostic pop") \
    } while (0)

使用

// 无参数返回
SuppressPerformSelectorLeakWarning(
    [_target performSelector:_action withObject:self]
);

// 有canshufanhui
id result;
SuppressPerformSelectorLeakWarning(
    result = [_target performSelector:_action withObject:self]
);

缺点:这个方法只是掩盖了警告,实质上并没有解决问题

二、处理警告
if (!target) return;
SEL selector = NSSelectorFromString(@"someMethod");
IMP imp = [target methodForSelector:selector];
void (*func)(id, SEL) = (void *)imp;
func(target, selector);

// 或者简写为,这里有入参
SEL selector = NSSelectorFromString(@"someMethod");
((void(*)(id, SEL, id))[target methodForSelector:selector])(target, selector, arg1);

// 如果selector有返回值
SEL selector = NSSelectorFromString(@"processRegion:ofView:");
IMP imp = [target methodForSelector:selector];
CGRect (*func)(id, SEL, CGRect, UIView *) = (void *)imp;
CGRect result = target ?
 func(target, selector, someRect, someView) : CGRectZero;

补:方法二其实也是掩盖编译的警告,如果selector不是target的,运行是奔溃,所以最好加上if([target respondToSelector:selector])判断,或者对imp进行空判断。

你可能感兴趣的:(performSeclector编译报可能导致内存泄漏的警告)