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

Ian*_*ell 19 objective-c clang automatic-ref-counting

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

@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
Run Code Online (Sandbox Code Playgroud)

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

PerformSelector may cause a leak because its selector is unknown
Run Code Online (Sandbox Code Playgroud)

经过一些研究后,我发现选择器可以属于具有不同内存要求的系列.目的是使行动失效,因此不应引起任何ARC困难并且应该适合none家庭.

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

__attribute__((objc_method_family(none)))
Run Code Online (Sandbox Code Playgroud)

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

jlu*_*yiv 17

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

首先,导入运行时消息头

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

    // [object performSelector:action];
    objc_msgSend(object, action);
Run Code Online (Sandbox Code Playgroud)


Mon*_*art 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
Run Code Online (Sandbox Code Playgroud)

感谢Scott Thompson(关于这个类似的问题:performSelector可能导致泄漏,因为它的选择器未知)的答案.


ser*_*rvn 5

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