Ios 如何阻止Xcode静态分析器报告对象泄漏?

Ios 如何阻止Xcode静态分析器报告对象泄漏?,ios,xcode,memory-leaks,Ios,Xcode,Memory Leaks,这是我对类对象的方法 + (XXObject*)objectWithValuesFromFromXml:(struct _TBXMLElement *)element { XXObject *object = [[XXObject alloc] init]; ... return object; } XCode表示存储在“object”中的对象存在潜在泄漏。 详细信息显示“3.对象泄漏:分配并存储到“对象”中的对象是从名称('objectWithValuesFromXm

这是我对类对象的方法

+ (XXObject*)objectWithValuesFromFromXml:(struct _TBXMLElement *)element
{
    XXObject *object = [[XXObject alloc] init];
    ...
    return object;
}
XCode表示存储在“object”中的对象存在潜在泄漏。

详细信息显示“3.对象泄漏:分配并存储到“对象”中的对象是从名称('objectWithValuesFromXml:')不以“copy”、“mutableCopy”、“alloc”或“new”开头的方法返回的。这违反了命名约定…”

但是文档()说“工厂方法的名称具有以下初始形式:

+ (id)typeRemainderOfMethodName
其中type是类名减去前缀后的值,RemainderOfMethodName通常以或开头。“


我能做什么?

您正在返回+1对象。只有以
copy
mutableCopy
alloc
new
开头的方法才能返回+1个对象。此静态分析器警告是正确的

您引用的文档也是正确的,工厂方法通常遵循这种命名约定。但它们不会返回+1对象。它们返回
autorelease
对象。Autorelease对象是当Autorelease池耗尽时(通常是当您退回到应用程序运行循环时)将释放的对象。但是通过返回autorelease对象,调用者有机会
保留该对象并将其用于自己的目的

顺便说一下,您可以通过在方法声明中显式指定
NS\u RETURNS\u RETAINED
来抑制此警告,该声明用于通知编译器您的方法不符合命名约定。不过,这是不可取的。此
NS\u RETURNS\u RETAINED
仅适用于现有方法不符合既定命名约定,但由于某种原因无法更改的情况(例如,已使用的API和更改内存语义会破坏现有代码)

我建议您:

  • 重命名此例程:

    + (XXObject*)newObjectWithValuesFromFromXml:(struct _TBXMLElement *)element
    {
        XXObject *object = [[XXObject alloc] init];
        ...
        return object;
    }
    
  • 返回
    autorelease
    对象:

    + (XXObject*)objectWithValuesFromFromXml:(struct _TBXMLElement *)element
    {
        XXObject *object = [[[XXObject alloc] init] autorelease];
        ...
        return object;
    }
    

另外,您通常不会在该方法声明中引用您的类,例如,您可以在方法声明中使用
instancetype
,在调用
alloc
时引用
self

+ (instancetype)objectWithValuesFromFromXml:(struct _TBXMLElement *)element
{
    XXObject *object = [[[self alloc] init] autorelease];
    ...
    return object;
}

这确保了如果该类曾经是子类,那么该方法也将继续为该子类工作。

您将返回一个+1对象。只有以
copy
mutableCopy
alloc
new
开头的方法才能返回+1个对象。此静态分析器警告是正确的

您引用的文档也是正确的,工厂方法通常遵循这种命名约定。但它们不会返回+1对象。它们返回
autorelease
对象。Autorelease对象是当Autorelease池耗尽时(通常是当您退回到应用程序运行循环时)将释放的对象。但是通过返回autorelease对象,调用者有机会
保留该对象并将其用于自己的目的

顺便说一下,您可以通过在方法声明中显式指定
NS\u RETURNS\u RETAINED
来抑制此警告,该声明用于通知编译器您的方法不符合命名约定。不过,这是不可取的。此
NS\u RETURNS\u RETAINED
仅适用于现有方法不符合既定命名约定,但由于某种原因无法更改的情况(例如,已使用的API和更改内存语义会破坏现有代码)

我建议您:

  • 重命名此例程:

    + (XXObject*)newObjectWithValuesFromFromXml:(struct _TBXMLElement *)element
    {
        XXObject *object = [[XXObject alloc] init];
        ...
        return object;
    }
    
  • 返回
    autorelease
    对象:

    + (XXObject*)objectWithValuesFromFromXml:(struct _TBXMLElement *)element
    {
        XXObject *object = [[[XXObject alloc] init] autorelease];
        ...
        return object;
    }
    

另外,您通常不会在该方法声明中引用您的类,例如,您可以在方法声明中使用
instancetype
,在调用
alloc
时引用
self

+ (instancetype)objectWithValuesFromFromXml:(struct _TBXMLElement *)element
{
    XXObject *object = [[[self alloc] init] autorelease];
    ...
    return object;
}

这确保了如果该类曾经是子类,那么该方法也将继续为该子类工作。

调用方法
xXObjectWithValuesFromFromXml
?“减去前缀”是什么意思?你用的是ARC还是MRC?我没有用ARC。什么是MRC?手动参考计数。有时也称为MRR(手动保留和释放)。不,autorelease将在自动释放池耗尽时释放对象(即,您退回到运行循环)。但是,无论谁调用此方法,都可以安全地保留此对象并将其用于自己的目的。从XML中调用方法
xXObjectWithValuesFromFromXml
?“减去前缀”是什么意思?你用的是ARC还是MRC?我没有用ARC。什么是MRC?手动参考计数。有时也称为MRR(手动保留和释放)。不,autorelease将在自动释放池耗尽时释放对象(即,您退回到运行循环)。但无论谁调用此方法,都可以安全地保留此对象并将其用于自己的目的。