My development environment:
我的开发环境:
Xcode 4.6.2
non-Automatic Reference Counting
非自动参考计数
For example, suppose we have a view controller called CertainViewController.m
, where a property called certainProperty
with attributes retain
and nonatomic
is declared.
例如,假设我们有一个名为CertainViewController.m的视图控制器,其中声明了一个名为certainProperty的属性,其属性为retain和nonatomic。
// CertainViewController.h
@interface CertainViewController : UIViewController
{
}
@property (retain, nonatomic) certainPropertyClass *listData;
// CertainViewController.m
- (void) viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
self.certainProperty = [[[certainPropertyClass alloc] init] autorelease];
// Among other initialization...
}
In the dealloc
method, there is implicit release
when we assign a new value to the the property certainProperty
. Not sure this is potentially hazardous or not.
在dealloc方法中,当我们为属性certainProperty赋值时,会有隐式释放。不确定这是否有潜在危险。
// CertainViewController.m
- (void) dealloc
{
self.certainProperty = nil;
}
Please share some insight, thank you :D
请分享一些见解,谢谢:D
4 个解决方案
#1
1
It's not strictly hazardous to release a variable with autorelease
in a non-ARC environment. However, it's not considered great practice to just tag on autorelease
to variables that you could manually release just as easily. autorelease
is really meant to be used when you want to get rid of an object as soon as the system no longer needs it, usually at a time you won't know. So while your code isn't strictly invalid, just know that it's best to manually call release
when you know exactly when to release an object, such as in your -dealloc
method.
在非ARC环境中使用自动释放释放变量并非严格危险。但是,将autorelease标记为可以轻松手动释放的变量并不是一种很好的做法。 autorelease真正意味着当你想要在系统不再需要时立即删除对象时,通常在你不知道的时候使用它。因此,虽然您的代码并非严格无效,但只要知道最好在确切知道何时释放对象时手动调用release,例如在-dealloc方法中。
#2
3
First, you code is wrong
首先,你的代码是错误的
// CertainViewController.m
- (void) viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
//[[[self.certainProperty alloc] init] autorelease]; // this is a nop if self.certainProperty is nil or crash if not nil
self.certainProperty = [[[YourPropertyClass alloc] init] autorelease];
// Among other initialization...
}
// CertainViewController.m
- (void) dealloc
{
self.certainProperty = nil;
[super dealloc]; // you must call super
}
Second, assuming certainProperty
is a retained property, assign a value to it will call retain
by the setter.
其次,假设CertainProperty是一个保留属性,为它赋值将由setter调用retain。
So doing
self.certainProperty = nil;
in dealloc
is required to balance the retain count otherwise certainProperty
will be leaked.
在dealloc中需要平衡保留计数,否则某些属性将被泄露。
#3
1
If you put it in the autorelease pool then you should let autorelease take care of it. Personally, I would handle the releasing of the object myself unless it requires an autorelease pool (say, some GUI object reference). But setting it to nil
is not a problem. You can perform operations all day long on a nil
object with no side effects.
如果你把它放在自动释放池中,那么你应该让autorelease处理它。就个人而言,我会自己处理对象的释放,除非它需要一个自动释放池(比如一些GUI对象引用)。但将其设置为零并不是问题。您可以在没有副作用的nil对象上整天执行操作。
#4
1
Stick to the convention. Don't defy the usual memory model unless there's something really important that can't be done otherwise.
坚持惯例。不要违反通常的内存模型,除非有一些非常重要的事情,否则无法做到。
release
decreases the retain count by 1. So it's not safe to call release
for it. One other object may have retained this, so the retain count is 1. So calling release
may cause it to be deallocated. That's in general.
release会将保留计数减少1.因此,为它调用release是不安全的。另一个对象可能保留了这个,因此保留计数为1.因此,调用release可能会导致它被释放。这是一般的。
If you have a retain
property, then assigning an object to it will result in retaining that object.
如果您有retain属性,则为其分配对象将导致保留该对象。
self.retainProperty = [[[MyObject alloc] init] autorelease]
Will result in retainCount = 1.
self.retainProperty = [[[MyObject alloc] init] autorelease]会导致retainCount = 1。
Note: The way you initialize certainProperty
in viewDidLoad:
is wrong. alloc
is a class method, it actually returns a new allocated object. So [[[self.certainProperty alloc] init] autorelease];
Will not set your property. Do as xlc said in his answer.
注意:在viewDidLoad中初始化CertainProperty的方式是错误的。 alloc是一个类方法,它实际上返回一个新的分配对象。所以[[[self.certainProperty alloc] init] autorelease];不会设置你的财产。正如xlc在他的回答中所说的那样。
#1
1
It's not strictly hazardous to release a variable with autorelease
in a non-ARC environment. However, it's not considered great practice to just tag on autorelease
to variables that you could manually release just as easily. autorelease
is really meant to be used when you want to get rid of an object as soon as the system no longer needs it, usually at a time you won't know. So while your code isn't strictly invalid, just know that it's best to manually call release
when you know exactly when to release an object, such as in your -dealloc
method.
在非ARC环境中使用自动释放释放变量并非严格危险。但是,将autorelease标记为可以轻松手动释放的变量并不是一种很好的做法。 autorelease真正意味着当你想要在系统不再需要时立即删除对象时,通常在你不知道的时候使用它。因此,虽然您的代码并非严格无效,但只要知道最好在确切知道何时释放对象时手动调用release,例如在-dealloc方法中。
#2
3
First, you code is wrong
首先,你的代码是错误的
// CertainViewController.m
- (void) viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
//[[[self.certainProperty alloc] init] autorelease]; // this is a nop if self.certainProperty is nil or crash if not nil
self.certainProperty = [[[YourPropertyClass alloc] init] autorelease];
// Among other initialization...
}
// CertainViewController.m
- (void) dealloc
{
self.certainProperty = nil;
[super dealloc]; // you must call super
}
Second, assuming certainProperty
is a retained property, assign a value to it will call retain
by the setter.
其次,假设CertainProperty是一个保留属性,为它赋值将由setter调用retain。
So doing
self.certainProperty = nil;
in dealloc
is required to balance the retain count otherwise certainProperty
will be leaked.
在dealloc中需要平衡保留计数,否则某些属性将被泄露。
#3
1
If you put it in the autorelease pool then you should let autorelease take care of it. Personally, I would handle the releasing of the object myself unless it requires an autorelease pool (say, some GUI object reference). But setting it to nil
is not a problem. You can perform operations all day long on a nil
object with no side effects.
如果你把它放在自动释放池中,那么你应该让autorelease处理它。就个人而言,我会自己处理对象的释放,除非它需要一个自动释放池(比如一些GUI对象引用)。但将其设置为零并不是问题。您可以在没有副作用的nil对象上整天执行操作。
#4
1
Stick to the convention. Don't defy the usual memory model unless there's something really important that can't be done otherwise.
坚持惯例。不要违反通常的内存模型,除非有一些非常重要的事情,否则无法做到。
release
decreases the retain count by 1. So it's not safe to call release
for it. One other object may have retained this, so the retain count is 1. So calling release
may cause it to be deallocated. That's in general.
release会将保留计数减少1.因此,为它调用release是不安全的。另一个对象可能保留了这个,因此保留计数为1.因此,调用release可能会导致它被释放。这是一般的。
If you have a retain
property, then assigning an object to it will result in retaining that object.
如果您有retain属性,则为其分配对象将导致保留该对象。
self.retainProperty = [[[MyObject alloc] init] autorelease]
Will result in retainCount = 1.
self.retainProperty = [[[MyObject alloc] init] autorelease]会导致retainCount = 1。
Note: The way you initialize certainProperty
in viewDidLoad:
is wrong. alloc
is a class method, it actually returns a new allocated object. So [[[self.certainProperty alloc] init] autorelease];
Will not set your property. Do as xlc said in his answer.
注意:在viewDidLoad中初始化CertainProperty的方式是错误的。 alloc是一个类方法,它实际上返回一个新的分配对象。所以[[[self.certainProperty alloc] init] autorelease];不会设置你的财产。正如xlc在他的回答中所说的那样。