PerformSelector may cause a leak because its selector is unknown

我们调用如下代码时[self performSelector:NSSelectorFromString(@"selectorName")];
会报警告PerformSelector may cause a leak because its selector is unknown

解决办法:
创建一个NSObejct的分类MSPerform

#import <Foundation/Foundation.h>

@interface NSObject (MSPerform)

/**
 调用名字为selectorName的对象方法
 
 @param selectorName 方法名
 */
- (void)performWithSelectorName:(NSString *)selectorName;

/**
 调用名字为selectorName参数为object的对象方法
 
 @param selectorName 方法名(注意方法名不要忘记:)
 @param object       参数(注意参数不能为基本类型,需要转成NSNumber)
 */
- (void)performWithSelectorName:(NSString *)selectorName withObject:(id)object;

/**
 调用名字为selectorName的类方法
 
 @param selectorName 方法名
 */
+ (void)performWithSelectorName:(NSString *)selectorName;

/**
 调用名字为selectorName参数为object的类方法
 
 @param selectorName 方法名(注意方法名不要忘记:)
 @param object       参数(注意参数不能为基本类型,需要转成NSNumber)
 */
+ (void)performWithSelectorName:(NSString *)selectorName withObject:(id)object;

@end
#import "NSObject+MSPerform.h"
#import <objc/message.h>

@implementation NSObject (MSPerform)

- (void)performWithSelectorName:(NSString *)selectorName {
    if ([self respondsToSelector:NSSelectorFromString(selectorName)]) {
        void (*action)(id, SEL) = (void (*)(id, SEL))objc_msgSend;
        action(self, NSSelectorFromString(selectorName));
    }
}

- (void)performWithSelectorName:(NSString *)selectorName withObject:(id)object {
    if ([self respondsToSelector:NSSelectorFromString(selectorName)]) {
        void (*action)(id, SEL, id) = (void (*)(id, SEL, id))objc_msgSend;
        action(self, NSSelectorFromString(selectorName), object);
    }
}

+ (void)performWithSelectorName:(NSString *)selectorName {
    if ([self respondsToSelector:NSSelectorFromString(selectorName)]) {
        void (*action)(id, SEL) = (void (*)(id, SEL))objc_msgSend;
        action(self, NSSelectorFromString(selectorName));
    }
}

+ (void)performWithSelectorName:(NSString *)selectorName withObject:(id)object {
    if ([self respondsToSelector:NSSelectorFromString(selectorName)]) {
        void (*action)(id, SEL, id) = (void (*)(id, SEL, id))objc_msgSend;
        action(self, NSSelectorFromString(selectorName), object);
    }
}

@end

消除警告只需要:
[self performSelector:NSSelectorFromString(@"actionName") withObject:@"param"];
替换成[self performWithSelectorName:@"actionName" withObject:@"param"];
[self performSelector:NSSelectorFromString(@"actionName")];
替换成[self performWithSelectorName:@"actionName"];
传的参数,一定要注意类型相匹配,最好在调用的方法里面加个判断。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容