【问题标题】:property assignment followed by autorelease属性分配,然后自动释放
【发布时间】:2011-10-07 21:34:11
【问题描述】:

我一直在考虑让我的代码少一些错误。在清理其他程序员的代码时,我已经多次看到这种情况,我想知道我的假设是否正确,即多线程环境中的调用不安全:

self.prop1 = [[[SomeClass alloc] init] autorelease];

我的想法是,如果在应用程序完成该函数之前,另一个线程干预并释放 prop1,那么在下一次 runLoop 时,如果 prop1 没有被另一个设置为 nil,则初始化的指针可能会再次释放线程。

Timeline:

*-----------------**-----------*
|                  |           |
|                  |           Thread 1 autoreleases prop1 when done with function
|                  |
|                  Thread 2 releases prop1
|
Thread 1 calls the above code and doesn't finish the function

我希望这对某人有意义,他们可以澄清或减轻我的担忧。

【问题讨论】:

  • "autorelease" 实际上并没有释放一个对象,它只是告诉引用计数系统在以后的某个时间点减少该对象的引用计数。

标签: objective-c ios properties release autorelease


【解决方案1】:

这取决于您的房产类型。如果你将 prop1 设置为保留/复制,那么你应该这样写:

@property (nonatomic, retain) id prop1;

if(self.prop1 == nil)
{
   SomeClass *obj = [[SomeClass alloc] init];
   self.prop1 = obj;
   [obj release];
}

如果你将 prop1 设置为 Assign 那么

@property (nonatomic, assign) id prop1;
if(self.prop1 == nil)
{
   SomeClass *obj = [[SomeClass alloc] init];
   self.prop1 = [obj retain];
   [obj release];
}

在 dealloc 中,您应该释放 prop1,例如

- (void)dealloc
{
  [prop1 release];
  [super dealloc];
}

如果你想安全地使用多线程,你可以选择以下之一:

1. Make property atomic
2. Use @synchronized over prop1
3. Use Mutex Lock

【讨论】:

  • 如果您的财产被转让,则意味着您不想保留它。
  • 感谢 Mark 改进格式…
【解决方案2】:

我认为您不必像通常那样担心线程安全。让多个线程写入同一个属性是一件坏事,应该避免(例如使用锁)。

您可以使用

摆脱自动释放
prop1 = [[SomeClass alloc] init];

相反,即不使用该属性。除非有必要,否则我从不使用自动释放,在这种情况下它不是。

【讨论】:

    猜你喜欢
    • 2012-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多