fetchRequestWithEntityName和initWithEntityName之间有什么区别?

时间:2012-04-27 11:43:44

标签: objective-c

虽然我意识到一个是类方法而另一个是实例方法,但它们在Apple文档中具有完全相同的描述,所以我不太了解不同的语法/用例。

3 个答案:

答案 0 :(得分:2)

它们的功能相同,但类方法返回一个自动释放的对象。也就是说,它可能是按照以下方式实现的:

+ (NSFetchRequest *)fetchRequestWithEntityName:(NSString *)entityName {
    return [[[NSFetchRequest alloc] initWithEntityName:entityName] autorelease];
}

这是Objective-C库中相当常见的模式,称为Class Factory methods

答案 1 :(得分:0)

这两个API之间的主要区别如下:

fetchRequestWithEntityName将为您提供一个自动释放对象,因此一旦事件循环结束,它将从内存中释放,直到您保留它为止。

但是initWithEntityName会给你一个由你释放的对象,否则会有内存泄漏。

答案 2 :(得分:0)

根据你所说的,如果他们真的拥有相同的用例,那么根据Apple使用的内存管理设计,唯一的区别就在于Objective-C上的垃圾收集。

每当你在一个对象上调用一个init方法时,你拥有它,并且当你不再需要该对象时,你有责任释放它。

当您调用任何其他类型的返回对象的方法时,该对象将添加到NSAutoreleasePool,并且当池耗尽时它为autorelease

您可以获得更多见解here

因此,按照Apple的方式,如果你不想这样保存对象以供进一步使用,你可以调用fetchRequestWithEntityName而不用担心在方法调用结束时释放对象。如果要将其另存为实例变量,请调用initWithEntityName方法。它们当然可以互换,但这种方法遵循苹果的指导方针来处理内存管理。

-(void)myMethod {
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

  id obj1 = [[Object alloc] initWithEntityName:...];
  id obj2 = [Object fetchRequestWithEntityName:...];

  //obj1 retain count is +1
  //obj2 retain count is +0 (likely autoreleased)

  [pool drain];

  //obj1 still exists
  //obj2 is no longer valid; may or may not have been deallocated 
}

基本上,fetchRequestWithEntityName是通过以下方式实现的:

+(id)fetchRequestWithEntityName:... {
  return [[[self class] alloc] initWithEntityName:...] autorelease];
}