ARC 禁止发送“保留”问题的显式消息

Posted

技术标签:

【中文标题】ARC 禁止发送“保留”问题的显式消息【英文标题】:ARC forbids explicit message send of 'retain' issue 【发布时间】:2012-08-06 07:13:55 【问题描述】:

我正在使用 Apple 指南中的这个非常简单的代码:

NSMutableData *receivedData;

// Create the request.
NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.apple.com/"]
                        cachePolicy:NSURLRequestUseProtocolCachePolicy
                    timeoutInterval:60.0];
// create the connection with the request
// and start loading the data
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if (theConnection) 
    // Create the NSMutableData to hold the received data.
    // receivedData is an instance variable declared elsewhere.
    receivedData = [[NSMutableData data] retain];
 else 
    // Inform the user that the connection failed.

但是对于receivedData = [[NSMutableData data] retain];这一行,Xcode 给了我一个错误:PushController.m:72:25: ARC forbids explicit message send of 'retain'

如何处理?我正在使用 Xcode 4.4.1

【问题讨论】:

这就是Arc right的意义所在,所以你不必保留和释放... Some questions about Automatic Reference Counting in ios5 SDK 的可能重复项 【参考方案1】:

您目前正在使用 ARC 来为您引用计数。 (ARC 是“自动引用计数”,iOS 5 的新功能)。因此您不需要手动保留或释放。您可以一起删除保留调用或通过执行以下操作关闭 ARC:

单击左侧导航视图中的项目名称,转到 Targets -> Build Phases 并将-fno-objc-arc 添加到任何相关文件的“编译器标志”中。

See here for info on removing.

See here for basic info on ARC.

【讨论】:

-fno-objc-arc 我将此解决方案视为初学者正在学习旧教程。【参考方案2】:

我解决了如下问题。代码是针对 Objective-C 的。

    无论您在哪个文件中编写了将图像从 CIImage 获取到 CGImageRef 的方法:

    CGImageRef cgImage = [_ciContext createCGImage:currentImage fromRect:[currentImage extent]];
    

    将该文件设为非 ARC。转到项目 -> BuildPhase -> ComplieSources -> 您的文件 -> 将 "-fno-objc-arc" 添加到您的文件中。

    如果您的项目中有 .pch 文件,请进行以下行注释:

    #if !__has_feature(objc_arc)
    #error This file must be compiled with ARC.
    #endif
    

    使用以下函数转到用于创建图像的方法:

    CGImageRef cgImage = [_ciContext createCGImage:currentImage fromRect:[currentImage extent]];
    

    像这样声明 _ciContext:

      在.h文件中,声明:

      @property (strong, nonatomic)   CIContext* ciContext;
      

      在您的方法中,创建上下文:

      EAGLContext *myEAGLContext = [[EAGLContext alloc]
              initWithAPI:kEAGLRenderingAPIOpenGLES2];
      _ciContext = [CIContext contextWithEAGLContext:myEAGLContext      options:nil];
      

      使用 _ciContext 创建图像。

      在同一个文件中写入以下方法:

       -(void)dealloc
       
          [super dealloc];
          [EAGLContext setCurrentContext:nil];
       
      

【讨论】:

【参考方案3】:

打开或关闭 ARC 是项目级别的设置,如果您需要在两种模式下工作的代码,您需要使用

#if __has_feature(objc_arc)
//dont do a release or a retain or autorelease
#else
//do the release
#endif

【讨论】:

实际上不,可以在每个实现的基础上禁用 arc,使用标志 -fno-objc-arc 用于编译器,就像 mrhappy 说的那样。您的选项部分正确,您可以使用该编译指示在 arc 文件中执行非 arc 内容,但通常实现文件都是相关的,您不需要使用一个文件处理 arc 和非 arc。

以上是关于ARC 禁止发送“保留”问题的显式消息的主要内容,如果未能解决你的问题,请参考以下文章

为啥在 ARC 中发送消息会导致保留周期警告,但属性集不会?

无法在表实体框架中插入标识列的显式值

不运行时接收消息,Xamarin Android上的显式广播和隐式广播

[UINavigationController 保留]:发送到已释放实例的消息

为啥在启用 ARC 的项目中不需要维护保留计数

LinQ 的显式问题