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将在自动释放池耗尽时释放对象(即,您退回到运行循环)。但无论谁调用此方法,都可以安全地保留此对象并将其用于自己的目的。