我在Objective-C中编写一个Button类,我如何在选择器上防止Clang的内存泄漏警告?

时间:2022-09-02 09:44:23

I'm writing a simple button class, something like this:

我在写一个简单的按钮类,像这样:

@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

I get the following warning from Clang on [object performSelector:action]:

我在[object performSelector:action]上收到如下警告:

PerformSelector may cause a leak because its selector is unknown

After some research I see that selectors can belong to families which have different memory requirements. The intention is for the action to return void, so it shouldn't cause any ARC difficulties and should fit in the none family.

经过一些研究,我发现选择器可以属于有不同记忆需求的家庭。其目的是使诉讼回归无效,因此不应造成任何弧形的困难,应适合无家庭。

It looks like the relevant piece of preprocessor code I want is, or is a variant of:

看起来我想要的相关预处理代码是,或者是:

__attribute__((objc_method_family(none)))

But where do I put that to tell Clang not to worry?

但是我把它放在哪里,告诉Clang不要担心?

4 个解决方案

#1


9  

In the LLVM 3.0 compiler in Xcode 4.2 you can suppress the warning as follows:

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

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

Thanks to Scott Thompson (about this similar question: performSelector may cause a leak because its selector is unknown) for the answer.

感谢Scott Thompson(关于这个类似的问题:performSelector可能会导致泄漏,因为它的selector是未知的)。

#2


17  

Because you're dynamically assigning action, the compiler sees a possible leak with ARC. In the future, the LLVM compiler may allow you to suppress the warning. Until then, you can avoid the warning by using the runtime's objc_msgSend() instead of -performSelector:.

因为您正在动态地分配操作,编译器会看到一个可能的带有圆弧的泄漏。将来,LLVM编译器可能允许您抑制警告。在此之前,可以使用运行时的objc_msgSend()而不是-performSelector:来避免警告。

First, import the runtime message header

首先,导入运行时消息头

#import <objc/message.h>
Next, replace performSelector: with objc_msgSend()

    // [object performSelector:action];
    objc_msgSend(object, action);

#3


5  

If you're writing new code, the best way to handle callbacks is to use blocks; they are both safer and more flexible than performSelector. See http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/Blocks/Articles/00_Introduction.html .

如果您正在编写新的代码,那么处理回调的最好方法是使用块;它们比performSelector更安全、更灵活。看到http://developer.apple.com/library/ios/文档/可可/概念/块/文章/ 00 _introduction.html。

#4


1  

I use this:

我用这个:

[object tryToPerform:action with:nil];

#1


9  

In the LLVM 3.0 compiler in Xcode 4.2 you can suppress the warning as follows:

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

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

Thanks to Scott Thompson (about this similar question: performSelector may cause a leak because its selector is unknown) for the answer.

感谢Scott Thompson(关于这个类似的问题:performSelector可能会导致泄漏,因为它的selector是未知的)。

#2


17  

Because you're dynamically assigning action, the compiler sees a possible leak with ARC. In the future, the LLVM compiler may allow you to suppress the warning. Until then, you can avoid the warning by using the runtime's objc_msgSend() instead of -performSelector:.

因为您正在动态地分配操作,编译器会看到一个可能的带有圆弧的泄漏。将来,LLVM编译器可能允许您抑制警告。在此之前,可以使用运行时的objc_msgSend()而不是-performSelector:来避免警告。

First, import the runtime message header

首先,导入运行时消息头

#import <objc/message.h>
Next, replace performSelector: with objc_msgSend()

    // [object performSelector:action];
    objc_msgSend(object, action);

#3


5  

If you're writing new code, the best way to handle callbacks is to use blocks; they are both safer and more flexible than performSelector. See http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/Blocks/Articles/00_Introduction.html .

如果您正在编写新的代码,那么处理回调的最好方法是使用块;它们比performSelector更安全、更灵活。看到http://developer.apple.com/library/ios/文档/可可/概念/块/文章/ 00 _introduction.html。

#4


1  

I use this:

我用这个:

[object tryToPerform:action with:nil];