19

我正在编写一个简单的按钮类,如下所示:

@interface MyButton : NSObject {
  id object;
  SEL action;
}
@property(strong) id object;
@property SEL action;
-(void)fire;
@end


@implementation MyButton

@synthesize object, action;

-(void)fire {
  [object performSelector:action];
}

@end

我从 Clang 收到以下警告[object performSelector:action]

PerformSelector may cause a leak because its selector is unknown

经过一些研究,我发现选择器可以属于具有不同内存要求的系列。目的是让动作返回无效,因此它不应该导致任何 ARC 困难并且应该适合none家庭。

看起来我想要的相关预处理器代码是,或者是以下的变体:

__attribute__((objc_method_family(none)))

但是我在哪里可以告诉 Clang 不要担心呢?

4

4 回答 4

17

因为您正在动态分配action,所以编译器会发现 ARC 可能存在泄漏。将来,LLVM 编译器可能允许您抑制警告。在此之前,您可以使用运行时的objc_msgSend()而不是-performSelector:.

一、导入运行时消息头

#import <objc/message.h>
接下来,替换performSelector:objc_msgSend()

    // [object performSelector:action];
    objc_msgSend(object, action);
于 2011-08-16T05:18:30.837 回答
9

在 Xcode 4.2 的 LLVM 3.0 编译器中,您可以按如下方式抑制警告:

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
    [object performSelector:action];
#pragma clang diagnostic pop

感谢 Scott Thompson (关于这个类似的问题:performSelector may cause a leak because its selector is unknown)的答案。

于 2012-03-16T10:15:35.813 回答
5

如果您正在编写新代码,处理回调的最佳方法是使用块;它们比 performSelector 更安全、更灵活。请参阅http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/Blocks/Articles/00_Introduction.html

于 2011-08-13T05:24:35.403 回答
1

我用这个:

[object tryToPerform:action with:nil];
于 2012-06-30T00:32:00.990 回答