Objective-C .mm在初始化器和类工厂方法中

时间:2023-01-15 15:08:17

This is a question related to Objective-C memory management.

这是与Objective-C内存管理相关的问题。

On the About Memory Management page there are some examples

在“关于内存管理”页面上有一些示例

- (NSString *)fullName {
   NSString *string = [[[NSString alloc] initWithFormat:@"%@ %@",
                                  self.firstName, self.lastName] autorelease];
   return string;
}

and the second one

和第二个

- (NSString *)fullName {
   NSString *string = [NSString stringWithFormat:@"%@ %@", 
                                  self.firstName, self.lastName];
   return string;
}

The only difference is that in the first example an initializer is called, and in the second a class factory method.

唯一的区别是在第一个示例中调用初始化程序,在第二个示例中调用类工厂方法。

Basic memory management rules section is said that after an alloc call I will own the object I allocated. So in the first example I allocate an object and at the same time initialize it. In this I own the object and have to release it. In the second example I don’t. But doesn’t the factory method stringWithFormat: do the same thing in one call, I mean allocating the object and initializing it?

基本的内存管理规则部分据说在alloc调用后我将拥有我分配的对象。所以在第一个例子中,我分配一个对象,同时初始化它。在这个我拥有对象,必须释放它。在第二个例子中,我没有。但是不是工厂方法stringWithFormat:在一次调用中做同样的事情,我的意思是分配对象并初始化它?

So the main question is, why don’t I have to release the object in the second example? are there any special memory management rules when implementing a class factory method?

所以主要的问题是,为什么我不必在第二个例子中释放对象?实现类工厂方法时是否有任何特殊的内存管理规则?

3 个解决方案

#1


2  

By convention, a class factory method will return an object that is in the autorelease pool. It has done the alloc, init, autorelease for you, just like in the first example. Unless you retain it, when the pool is drained, it will be released.

按照惯例,类工厂方法将返回自动释放池中的对象。它已经为你完成了alloc,init,autorelease,就像在第一个例子中一样。除非您保留它,否则当池耗尽时,它将被释放。

#2


1  

In the second example, you didn't create the string. You only create objects by invoking methods that begin with alloc, new, copy, or mutableCopy.

在第二个示例中,您没有创建字符串。您只能通过调用以alloc,new,copy或mutableCopy开头的方法来创建对象。

You may take ownership, if you like, by invoking retain, but then you're also responsible for invoking release. In this example, there's no need. You don't need the string any more. What the caller does with it is their responsibility.

如果您愿意,您可以通过调用retain获取所有权,但是您还负责调用release。在这个例子中,没有必要。你不再需要字符串了。来电者做的是他们的责任。

When invoking a factory method like this, you typically receive an autoreleased object. But you don't really need to think about that. Because you didn't create it (because you didn't use a method beginning with alloc, new, copy, or mutableCopy to get that string), all you need to do is think about the retain count delta -- do you need to retain it to keep it from disappearing from underneath you. Since it's just being returned to the caller, the answer in this example is no.

在调用这样的工厂方法时,通常会收到一个自动释放的对象。但你真的不需要考虑这个问题。因为你没有创建它(因为你没有使用以alloc,new,copy或mutableCopy开头的方法来获取该字符串),你需要做的就是考虑保留计数增量 - 你需要吗?保留它以防止它从你下面消失。因为它只是被返回给调用者,所以这个例子中的答案是否定的。

#3


0  

You are right, the factory method internally calls the alloc, and thus returns retained object, but it adds that object to the nearest autorelease pool, so when that pool will be drained, the object will be released.

你是对的,工厂方法在内部调用alloc,因此返回保留对象,但它将该对象添加到最近的自动释放池,因此当该池被耗尽时,该对象将被释放。

#1


2  

By convention, a class factory method will return an object that is in the autorelease pool. It has done the alloc, init, autorelease for you, just like in the first example. Unless you retain it, when the pool is drained, it will be released.

按照惯例,类工厂方法将返回自动释放池中的对象。它已经为你完成了alloc,init,autorelease,就像在第一个例子中一样。除非您保留它,否则当池耗尽时,它将被释放。

#2


1  

In the second example, you didn't create the string. You only create objects by invoking methods that begin with alloc, new, copy, or mutableCopy.

在第二个示例中,您没有创建字符串。您只能通过调用以alloc,new,copy或mutableCopy开头的方法来创建对象。

You may take ownership, if you like, by invoking retain, but then you're also responsible for invoking release. In this example, there's no need. You don't need the string any more. What the caller does with it is their responsibility.

如果您愿意,您可以通过调用retain获取所有权,但是您还负责调用release。在这个例子中,没有必要。你不再需要字符串了。来电者做的是他们的责任。

When invoking a factory method like this, you typically receive an autoreleased object. But you don't really need to think about that. Because you didn't create it (because you didn't use a method beginning with alloc, new, copy, or mutableCopy to get that string), all you need to do is think about the retain count delta -- do you need to retain it to keep it from disappearing from underneath you. Since it's just being returned to the caller, the answer in this example is no.

在调用这样的工厂方法时,通常会收到一个自动释放的对象。但你真的不需要考虑这个问题。因为你没有创建它(因为你没有使用以alloc,new,copy或mutableCopy开头的方法来获取该字符串),你需要做的就是考虑保留计数增量 - 你需要吗?保留它以防止它从你下面消失。因为它只是被返回给调用者,所以这个例子中的答案是否定的。

#3


0  

You are right, the factory method internally calls the alloc, and thus returns retained object, but it adds that object to the nearest autorelease pool, so when that pool will be drained, the object will be released.

你是对的,工厂方法在内部调用alloc,因此返回保留对象,但它将该对象添加到最近的自动释放池,因此当该池被耗尽时,该对象将被释放。