【问题标题】:why warning with my performSelector为什么用我的 performSelector 警告
【发布时间】:2012-05-18 20:31:55
【问题描述】:

下面是一个简单的 PerformSelector,它向 obj 发送消息以执行循环方法。一切正常,但我收到以下黄色警告。

PerformSelector 可能会导致泄漏,因为它的选择器是未知的。

#import "MyClass.h"
#import <Foundation/Foundation.h>

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        MyClass *obj = [[MyClass alloc]init];

        SEL mySel = @selector(looping);
        [obj performSelector:mySel];
    }
    return 0;
}

这个警告没有意义,因为 performSelector 必须知道 mySel 因为循环方法确实被调用 - 有什么想法吗??


更新

MyClass.h

#import <Foundation/Foundation.h>

@interface MyClass : NSObject

-(void)looping;

@end

MyClass.m

#import "MyClass.h"

@implementation MyClass

-(void)looping{

    NSLog(@"Hey, i'm looping");

}

@end

【问题讨论】:

    标签: objective-c memory-management automatic-ref-counting performselector


    【解决方案1】:

    更新——真正的答案

    这是 ARC 特有的:

    performSelector may cause a leak because its selector is unknown

    简而言之,ARC 使用基于命名约定和绑定到选择器的任何附加属性的信息。当按名称访问选择器并通过performSelector: 系列方法执行它时,该信息会丢失,编译器会警告您必须对引用计数做出一些假设,因为此信息已被删除。

    简而言之,您发布的特定程序是安全的我们鼓励您使用对 ARC 友好的替代方案。

    之前的回应

    选择器的声明不需要对当前翻译可见才能调用它。

    允许编译器假定类和实例方法的参数和返回类型的默认类型(id 是默认值)。

    有几个编译器警告可以警告您这些可疑的操作。

    您可能忘记在@interface 中声明选择器looping,或者您可能省略了冒号,如果它有参数:looping: 将是它的名称。

    【讨论】:

    • 感谢您的帮助,但作为一个新手,我仍然有点困惑。如果可能的话,您能否通过不声明当前翻译来解释或更好地发送您的意思的示例。循环方法在接口中,不需要冒号,因为它不接受任何参数(它只是注销一个字符串)。
    • @pete 感谢您扩展您的帖子。我已经用真实的答案更新了它。
    • 这解释了它,是的,我已经打开了 ARC。谢谢
    【解决方案2】:

    这个警告是因为你没有告诉编译器选择器所在的位置,导入文件所在的位置或将选择器添加到头文件应该在的位置

    【讨论】:

    • 选择器是来自 MyClass 的类方法。我已将 #import "MyClass.h" 放在 main 的顶部 -
    • 你在你的 MyClass.h 中声明了吗?
    • 编译器只知道预先声明到一行或通过某个库包含的东西
    • 是的,该方法在头文件中声明 - 我刚刚进行了编辑以显示所有文件
    • ok 然后 if([obj respondsToselecto:mySel]){[obj performSelector:mySel];}
    猜你喜欢
    • 2012-08-07
    • 2015-01-31
    • 2011-11-15
    • 2013-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-25
    相关资源
    最近更新 更多