一般目标-C类方法问题

时间:2010-01-15 23:30:32

标签: objective-c oop object class class-design

我有一个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,没有实例方法......


修改

好吧,显然大多数人都没有看到该对象的发布,所以我想我不清楚这一点 - 在将对象分配给视图的属性之后,它将被释放。 尽管如此,我还是看到了返回自动释放对象的做法。不幸的是,当我这样做时,我的应用程序崩溃了。也许是因为我在一个单独的线程/自动释放池中运行整个处理? 我将测试一些配置,并告诉你它是如何进行的。

3 个答案:

答案 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];

这里有几点说明:

  1. 我使用方法签名objXWithIdentifier...,因为我不确定@“09384f9a”字符串。如果是地址,您可以使用objXWithAddress...。如果是参考号,您可以使用objXWithReferenceNumber...

  2. 我必须仔细研究才能确定。 performSelectorOnMainThread...方法保留其参数,因此在主线程上调用方法之前不会担心被释放的对象。

答案 2 :(得分:1)

来自Memory Management Programming Guide for CocoaYou 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).如果您的方法不以任何这些前缀开头,则应返回自动释放的对象。然后,如果需要将对象保持更长时间,该方法的调用者可以保留该对象。