我有一个iPhone应用程序,它有一些方法从Web收集信息,然后创建一个对象,它将这些信息保存为属性(假设我将获得x类型的对象)。由于我可能需要来自应用程序中各个点的那些对象,因此我将该方法的一个实例创建为单个实现文件,并将该文件称为“GetDetails.m”(+ h)。在这个方法中,我只使用类方法*,(在我创建对象x的方法中)创建了Object,并使用该方法从Web收集的信息填充其属性。
+ (ObjX *)getObjectX:(NSString *key) withParameters:(NSArray *)parameters;
在这种方法中,我的ObjX充满了信息......
ObjX *objectX = [[ObjX alloc] init];
(...)
objectX.name = gatheredName; // etc
(...)
return objectX;
所以我的类方法是在应用程序内的几个点调用的(顺便说一下,来自一个单独的线程):
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
ObjX *myObject;
myObject = [GetDetails getObjectX:@"09384f9a" withParameters:nil];
[self performSelectorOnMainThread:@selector(doStuffWithNewObject:) withObject:myObject waitUntilDone:NO];
[pool release];
我无法摆脱这种方法不是最优的感觉。 Xcode分析器还告诉我返回objectX可能存在泄漏。
也许有人可以指出我正确的方向以及我应该如何分解一般的功能。
*它也没有init和dealloc方法,没有ivars,没有实例方法......
修改
好吧,显然大多数人都没有看到该对象的发布,所以我想我不清楚这一点 - 在将对象分配给视图的属性之后,它将被释放。 尽管如此,我还是看到了返回自动释放对象的做法。不幸的是,当我这样做时,我的应用程序崩溃了。也许是因为我在一个单独的线程/自动释放池中运行整个处理? 我将测试一些配置,并告诉你它是如何进行的。
答案 0 :(得分:1)
有一件事对我来说很重要的是,每次你打电话给你的班级方法时,你都会这样做:
ObjX *objectX = [[ObjX alloc] init];
在这里,您要创建一个对象的新实例。但是,您的代码示例并未显示您正在发布它的任何位置。记住alloc给对象一个ref计数。此外,通过调用方法getXXX,您将违反内存管理约定。这意味着您正在检索某个您不拥有的对象的引用。由于情况并非如此,您至少应该调用您的方法newXXX或createXXX来暗示该调用者负责分配的内存。更好的方法是自动释放它并由调用者保留它。
答案 1 :(得分:1)
分析仪会让你感到悲伤,因为当你返回它们时你没有autorelease
你的物体。通常的方法如下:
ObjX *objectX = [[ObjX alloc] init];
...
return [objectX autorelease];
现在,就实现而言,这听起来像是一个使用类别的地方。我会做这样的事情:
<强> GetDetails_ObjX.h 强>
@interface ObjX (GetDetails)
+ (ObjX *)objXWithIdentifier:(NSString *)ident parameters:(NSArray *)params;
@end
<强> GetDetails_ObjX.m 强>
@implementation ObjX (GetDetails)
+ (ObjX *)objXWithIdentifier:(NSString *)ident parameters:(NSArray *)params
{
ObjX *objectX = [[ObjX alloc] init];
...
return [objectX autorelease];
}
@end
<强> GetDetails.h 强>
#import "GetDetails_ObjX.h"
#import "GetDetails_ObjY.h"
...
此设置可按如下方式使用:
#import "GetDetails.h"
...
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
ObjX *myObject;
myObject = [ObjX objectXWithIdentifier:@"09384f9a" parameters:nil];
[self performSelectorOnMainThread:@selector(doStuffWithNewObject:)
withObject:myObject
waitUntilDone:NO];
[pool release];
这里有几点说明:
我使用方法签名objXWithIdentifier...
,因为我不确定@“09384f9a”字符串是。如果是地址,您可以使用objXWithAddress...
。如果是参考号,您可以使用objXWithReferenceNumber...
等
我必须仔细研究才能确定。 performSelectorOnMainThread...
方法保留其参数,因此在主线程上调用方法之前不会担心被释放的对象。
答案 2 :(得分:1)
来自Memory Management Programming Guide for Cocoa:
You own any object you create.
You “create” an object using a method whose name begins with “alloc” or “new” or contains “copy” (for example, alloc, newObject, or mutableCopy).
如果您的方法不以任何这些前缀开头,则应返回自动释放的对象。然后,如果需要将对象保持更长时间,该方法的调用者可以保留该对象。