对象实例可以自行释放吗?

时间:2011-06-23 12:25:14

标签: ios memory-management memory-leaks

我需要创建一些等待某个事件的对象。当等待事件被触发时,对象会做出一些事情,然后不再有任何理由生存。

我不想维护已创建对象的列表,所以我想做这样的事情:

main() {
     Waiter* myWaiter1 = [[Waiter alloc] initAndWaitForEvent:xxxxxxxxxx];
     Waiter* myWaiter2 = [[Waiter alloc] initAndWaitForEvent:xxxxxxxxxx];
     Waiter* myWaiter3 = [[Waiter alloc] initAndWaitForEvent:xxxxxxxxxx];
     Waiter* myWaiter4 = [[Waiter alloc] initAndWaitForEvent:xxxxxxxxxx];
     .... 
     /* myWaiterx are retained */
     /* I don't release them */
}

服务员

- (void) catchSomeEvent:(...*)theEvent {
   // do what is expected

   [self release];  // Release self
   /* the release is there */
}

这会起作用,并且工作正常吗?

3 个答案:

答案 0 :(得分:3)

当有人照顾服务员时,我觉得更好,但你的代码很好。物体可以做到这一点,没有技术障碍可以阻止它。标准库中的某些类已经执行了类似的操作,例如UIAlertView

我不认为静态分析器会喜欢你当前的API。它可能会抱怨泄漏;最好稍微调整一下界面。

@interface Waiter : NSObject {}
- (id) init;
- (void) startWaitingForEvent: (id) event;
@end

@implementation Waiter

- (void) startWaitingForEvent: (id) event
{
    [self retain];
    …
}

- (void) eventReceived
{
    …
    [self release];
}

@end

然后用户代码中的内存管理看起来更好:

- (void) dispatchWaiters {
    Waiter w1 = [[Waiter alloc] init];
    [w1 startWaitingForEvent:…];
    [w1 release];
}

答案 1 :(得分:2)

一个物体不能自杀。它既可以被你杀死(你发送的代码来杀死它),也可以被职业杀手NSAutoreleasePool杀死。如果你拥有它,你必须杀死它。

警告:如果它没有按时死亡,人口会增加并且会使记忆混乱。

- )

答案 2 :(得分:1)

在某些情况下使用[self release];,例如初始值设定项(以强制某些方式所需的变量),例如:

<强> SomeClass.m

- (id)initWithString:(NSString *)string 
{
   self = [super init];
   if (self) 
   {
       if (string == nil) 
       {
           [self release];
           return nil;
       }

       // if required values are provided, we can continue ...
   }
   return self;
}

- (id)init 
{
   return [self initWithString:nil];
}

来电者会这样称呼:

- (void)testInitializer 
{
    SomeClass *classInstance1 = [[SomeClass alloc] initWithString:@"bla"];
    // classInstance1 != nil, any method calls will work as expected ...

    SomeClass *classInstance2 = [[SomeClass alloc] initWithString:nil];
    // classInstance2 == nil, will ignore any method calls (fail silently)

    SomeClass *classInstance3 = [[SomeClass alloc] init];
    // classInstance3 == nil, will ignore any method calls (fail silently)
}

我猜是因为上述工作正常,你不应该有任何问题,虽然它似乎不是一个非常干净的解决方案。