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

发布于 2024-11-29 10:57:17 字数 802 浏览 0 评论 0原文

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

@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

我在 [object PerformSelector:action] 上从 Clang 收到以下警告:

PerformSelector may cause a leak because its selector is unknown

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

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

__attribute__((objc_method_family(none)))

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

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]:

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

一袭白衣梦中忆 2024-12-06 10:57:17

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

首先导入运行时消息头

#import <objc/message.h>

Next, replace performSelector: with objc_msgSend()

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

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:.

First, import the runtime message header

#import <objc/message.h>

Next, replace performSelector: with objc_msgSend()

    // [object performSelector:action];
    objc_msgSend(object, action);
夜光 2024-12-06 10:57:17

在 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 可能会导致泄漏,因为其选择器未知)的答案。

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

#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.

三寸金莲 2024-12-06 10:57:17

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

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 .

独木成林 2024-12-06 10:57:17

我用这个:

[object tryToPerform:action with:nil];

I use this:

[object tryToPerform:action with:nil];
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文