Objective-C引用是否分配字段或创建新实例

时间:2013-02-15 02:10:40

标签: objective-c memory memory-management reference field

比如说我有MyClass的以下定义:

@interface MyClass
{
    ClassWithBigMemoryUsage* cwbmu;
}

-(void) setClassWithBigMemoryUsage:(ClassWithBigMemoryUsage*) assignment; // where cwbmu = assignment;

如果我将myClassInstance创建为MyClass个实例,将cwbmuInstance创建为ClassWithBigMemoryUsage个实例,然后调用[myClassInstance setClassWithBigMemoryUsage:cwbmuInstance]设置cwbmuInstance作为myClassInstance的字段,将为ClassWithBigMemoryUsage创建对象myClassInstance的新实例(意味着额外分配的内存),或者仅引用myClassInstance&#39} s字段为cwbmuInstance(表示没有为对象分配额外的内存)。

1 个答案:

答案 0 :(得分:3)

所有Objective-C对象都是指针(因此*中的ClassWithBigMemoryUsage *),因此对象将通过引用传递,您不必担心它在传递时被复制

但是,当方法实际执行赋值时是否复制对象显然取决于setter方法的实现。如果你这样做:

cwbmu = assignment;

您只需设置指针值,不进行复制。当然,因为它是一个对象,你应该保留它,通过这样做:

[cwbmu autorelease];
cwbmu = [assignment retain];

但结果是一样的。真正可靠地复制Objective-C实例的唯一方法是显式发送copy消息:

[cwbmu autorelease];
cwbmu = [assignment copy];

这仅适用于符合NSCopying协议的类。

最后请注意,如果您使用@property声明以及@synthesize'd方法,则可以指定您希望使用哪种行为。通过以下三种方式声明属性将分别使用所描述的三种方式:

@property (assign) ClassWithBigMemoryUsage* cwbmu;
@property (retain) ClassWithBigMemoryUsage* cwbmu;
@property (copy) ClassWithBigMemoryUsage* cwbmu;

另请注意,在ARC下,此内存管理已为您完成,因此您无法直接控制它。相反,您使用weak选项(而不是assign)或strong选项(而不是retain),即使旧名称仍然有效,新名字使你更清楚你在做什么。 copy选项在ARC下仍然有效。

最后,如果您使用ARC,但使用@property,则默认情况下,实例变量将被管理为strong。您可以通过将__weak添加到他们的ivar声明中来更改此设置。但是,所有体系结构都不支持weak,在这种情况下可以使用__unsafe_unretained代替,但在后一种情况下,释放的对象指针将归零(设置为nil),在使用__weak时将会是。{/ p>