字典的深层复制在 Xcode 4.2 中给出分析错误

2023-12-07

我在 NSDictionary 类别中有以下方法来进行深度复制,效果很好。

我刚刚从 Xcode 4.1 升级到 4.2,Analyze 函数针对此代码给出了两个分析器警告,如下所示:

- (id)deepCopy;
{
    id dict = [[NSMutableDictionary alloc] init];
    id copy;

    for (id key in self)
    {
        id object = [self objectForKey:key];

        if ([object respondsToSelector:@selector(deepCopy)])
            copy = [object deepCopy];
        else
            copy = [object copy];

        [dict setObject:copy forKey:key];

        // Both -deepCopy and -copy retain the object, and so does -setObject:forKey:, so need to -release:
        [copy release];  // Xcode 4.2's Analyze says this is an incorrect decrement of the reference count?!
    }

    return dict;  // Xcode 4.2's Analyze says this is a potential leak
}

这些错误是否存在于 Xcode 分析器中,或者我可以进行哪些更改来避免这些警告?

我还没有使用 ARC,但我很感兴趣是否需要进行其他更改来支持此方法的 ARC。


大概是因为deepCopy才不是begin与前缀copy.

所以你可能想改变成类似的东西copyWithDeepCopiedValues(或类似的东西),然后查看分析器是否对此进行标记。

Update

正如 Alexsander 指出的,您可以使用属性来表示引用计数意图。这应该(IMO)是规则的例外,并且很少使用(如果有的话)。就我个人而言,我不会对 objc 方法使用属性,因为它很脆弱。

到目前为止我使用过的唯一属性是consume,并且每次我使用这些属性都是在静态类型上下文中(例如 C 函数和 C++ 函数和方法)。

应尽可能避免使用属性的原因:

1)为了程序员的利益,坚持约定。代码比较清晰,不需要看文档。

2)该方法是脆弱的。您仍然可以引入引用计数不平衡,并且属性可以用于由于属性冲突而引入构建错误。

以下案例均启用了 ARC 构建:

Case #1

#import <Foundation/Foundation.h>

@interface MONType : NSObject

- (NSString *)string __attribute__((objc_method_family(copy)));

@end

@implementation MONType

- (NSString *)string
{
    NSMutableString * ret = [NSMutableString new];
    [ret appendString:@"MONType"];
    return ret;
}

@end

int main (int argc, const char * argv[])
{
    @autoreleasepool {
        id obj = nil;
        if (random() % 2U) {
            obj = [[NSAttributedString alloc] initWithString:@"NSAttributedString"];
        }
        else {
            obj = [MONType new];
        }
        NSLog(@"Result: %@, %@", obj, [obj string]);
    }
    /* this tool's name is ARC, dump the leaks: */
    system("leaks ARC");
    return 0;
}

该程序产生以下错误:error: multiple methods named 'string' found with mismatched result, parameter type or attributes.

太好了,编译器正在尽其所能来防止这些问题。这意味着属性冲突可能会导致翻译错误。这是bad因为当组合重要的代码库并且属性发生冲突时,您将需要纠正错误并更新程序。这也意味着在使用属性时,简单地将其他库包含在翻译单元中可能会破坏现有程序。

Case #2

Header.h

extern id NewObject(void);

Header.m

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

@interface MONType : NSObject

- (NSString *)string __attribute__((objc_method_family(copy)));

@end

@implementation MONType

- (NSString *)string
{
    NSMutableString * ret = [NSMutableString new];
    [ret appendString:@"-[MONType string]"];
    return ret;
}

@end


id NewObject(void) {
    id obj = nil;
    if (random() % 2U) {
        obj = [[NSAttributedString alloc] initWithString:@"NSAttributedString"];
    }
    else {
        obj = [MONType new];
    }
    return obj;
}

main.m

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

int main (int argc, const char * argv[])
{
    @autoreleasepool {
        for (size_t idx = 0; idx < 8; ++idx) {
            id obj = NewObject();
            NSLog(@"Result: %@, %@", obj, [obj string]);
        }
    }
    /* this tool's name is ARC, dump the leaks: */
    system("leaks ARC");
    return 0;
}

好的。这只是bad。我们引入了泄漏,因为翻译单元中没有必要的信息。这是泄漏报告:

leaks Report Version:  2.0
Process 7778: 1230 nodes malloced for 210 KB
Process 7778: 4 leaks for 192 total leaked bytes.
Leak: 0x1005001f0  size=64  zone: DefaultMallocZone_0x100003000   __NSCFString  ObjC  CoreFoundation  mutable non-inline:  "-[MONType string]"
Leak: 0x100500320  size=64  zone: DefaultMallocZone_0x100003000   __NSCFString  ObjC  CoreFoundation  mutable non-inline:  "-[MONType string]"
Leak: 0x100500230  size=32  zone: DefaultMallocZone_0x100003000  has-length-byte:  "-[MONType string]"
Leak: 0x100500390  size=32  zone: DefaultMallocZone_0x100003000  has-length-byte:  "-[MONType string]"

注意:计数可能会有所不同,因为我们使用了random()

这意味着因为MONType不可见main(),编译器将 ARC 属性绑定到当前 TU 可见的方法(即string来自基金会的声明,所有这些都遵循惯例)。结果,编译器出错,我们就可以在程序中引入泄漏。

Case 3

使用类似的方法,我还能够引入负引用计数不平衡(过早发布或消息僵尸)。

注意:未提供代码,因为案例 #2 已经说明了如何实现引用计数不平衡。

结论

您可以通过坚持约定而不是使用属性来避免所有这些问题并提高可读性和可维护性。

让对话回到非 ARC 代码:使用属性会使手动内存管理对于程序员的可读性以及可以帮助您的工具(例如编译器、静态分析)来说变得更加困难。如果程序相当复杂,以至于工具无法检测到此类错误,那么您应该重新考虑您的设计,因为对于您或其他人来说调试这些问题同样复杂。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

字典的深层复制在 Xcode 4.2 中给出分析错误 的相关文章

随机推荐

  • “函数模板已被定义”,具有互斥的 `enable_if`

    对于以下代码 MSVC 会产生错误 函数模板已被定义 template
  • WPF 中的最小化窗口位置

    我试图将自定义对话框的位置保存到用户注册表中 以便当他们重新加载同一对话框时 它会出现在他们之前移动或调整其大小的同一位置 我正在保存窗口的 X 位置 Y 位置宽度和高度 除了最小化对话框外 一切正常 如果对话框最小化并且用户右键单击任务栏
  • 使用 env var 作为选择参数值的声明式管道

    免责声明 我可以使用 Active Choices 插件实现我正在寻找的行为 但我真的希望它能够在 Jenkinsfile 中工作并由 scm 控制 因为在我们可能需要的每个作业上配置 Active Choices 是很乏味的 由于它与 J
  • Equinox (OSGi) 和 JPA/Hibernate - 查找实体

    我正在尝试在 OSGi Equinox 环境中使用 Hibernate Spring 如果我明确地将其指向 Persistence xml 中的实体类 效果会很好
  • 检测何时创建新的虚拟驱动器

    我怎么知道什么真地穴卷安装在计算机上吗 Note我已经知道可以挂载哪些文件了 换句话说 唯一可以安装的卷是 C Vol1 tc C Vol2 tc and C Vol3 tc 我如何知道卷何时被卸载 我设法通过使用 net 类来做到这一点F
  • 指令中未收到广播

    我的控制器之间存在父子控制器关系
  • 仅当使用列列表且 IDENTITY_INSERT 为 ON 时,才能指定表“Table”中标识列的显式值

    有人知道这个错误是什么 仅当使用列列表且 IDENTITY INSERT 为 ON 时 才能指定表 HD AANVRAAG FASE 中标识列的显式值 描述 执行当前 Web 请求期间发生未处理的异常 请查看堆栈跟踪以获取有关错误及其在代码
  • 如何使用VBA为大文件生成md5哈希值?

    我有以下函数来生成文件的 md5 哈希值 这些函数非常适合小文件 但会崩溃并生成运行时错误 7 内存不足当我尝试对超过 250 MB 的文件进行哈希处理时 我实际上不知道它会破坏到哪个确切大小 但低于 200 MB 的文件工作正常 我不明白
  • PHP 中的“无法在写入上下文中使用函数返回值”错误

    致命错误 无法使用函数返回 第 3 行写入上下文中的值 在什么情况下会触发此类错误 我的程序 QUERY VARIABLE query select form user where user name user name and user
  • 使用自定义角度指令扩展 ng-bootstrap popover 组件

    我试图实现的是扩展 ngbPopover 指令并将所有这些属性包装在自定义指令中 而不是仅显示它们以包含我的指令 例如 我正在使用 ngbpopover 如下所示
  • 如何将模块添加到项目的 Eclipse Oxygen 模块路径?

    我有一个项目 今天有几个罐子作为 参考库 相反 我想将它们添加为模块路径上的自动模块 这样我就可以在我的 module info java 中需要它们 如何将 jar 添加到 Eclipse Oxygen 中的模块路径 以下是我如何让它工作
  • 文档正文为空

    我有一个正在使用 Mootools 1 2 4 的页面MediaboxAdvanced作为灯箱 由于特定的 javascript 错误 我似乎无法让该功能正常工作 文档正文为空 Mediabox 初始化时 document body ado
  • Process.Start 的 VB 6 等效项是什么?

    我真的被这一行困住了 在 vb net 中这很容易 但是在 vb6 中如何做到这一点 试图从谷歌搜索几个小时 但一无所获 感觉几乎很尴尬 这是代码 网 Process Start runme exe parameter1 parameter
  • MATLAB 中的特征选择方法?

    我正在尝试在 MATLAB 中使用 SVM 进行一些文本分类 并且真的很想知道 MATLAB 是否有任何特征选择方法 Chi Sq MI 因为我想尝试各种方法并保持最好的方法 我没有时间全部实施 这就是我在 MATLAB 中寻找此类方法的原
  • NetConnection.Call.Failed 在 Flex3/Tomcat/BlazeDS/Spring 中偶尔发生

    我有一个很大的问题 我使用 Flex3 Tomcat BlazeDS Spring 编写了一个大型应用程序 该应用程序在本地开发时运行良好 在部署到公共开发环境时运行良好 但在部署到我们的测试环境时经常失败 当远程处理请求花费大量时间 超过
  • 在每个套接字的基础上调整 MTU?

    我想知道是否有任何方法可以调整 在 Linux 系统上 给定套接字的 MTU 使 IP 层分段成小于实际设备 MTU 的块 当我说对于给定的套接字时 我并不是指在拥有该套接字的应用程序代码中以编程方式 而是在外部 例如通过 sysfs 条目
  • 我可以更改 json_encode 的默认选项吗

    我在 PHP 文档中找不到任何与此相关的内容 因此如果不将 json encode 包装在专有函数中 这可能是不可能的 但我想知道是否可以在 php ini 或其他地方设置 json encode 函数的默认选项 目的是始终启用 JSON
  • iOS6 - 在应用程序内购买并从 Apple 服务器下载

    我能够成功进行应用内购买并从 Apple 服务器下载内容并使用它 我的应用内购买内容是非消耗性的 所以我在我的应用程序中提供 恢复 按钮现在 当用户按下 恢复 按钮时 我将调用该方法 restoreCompletedTransactions
  • 将图像转换为颜色数组

    我在 Java 中加载图像并希望将其转换为 RGB 数组 以便我可以读取每个像素的颜色 我在谷歌上搜索 但我只找到了如何将颜色数组转换为图像 以下几行说明了 API 方法的用法 BufferedImage bi ImageIO read n
  • 字典的深层复制在 Xcode 4.2 中给出分析错误

    我在 NSDictionary 类别中有以下方法来进行深度复制 效果很好 我刚刚从 Xcode 4 1 升级到 4 2 Analyze 函数针对此代码给出了两个分析器警告 如下所示 id deepCopy id dict NSMutable