Может ли экземпляр объекта освободить себя? - PullRequest
2 голосов
/ 23 июня 2011

Мне нужно создать несколько объектов, которые будут ждать какого-то события. Когда инициируется ожидаемое событие, объект делает некоторые вещи, и у него больше нет причин жить.

Я не хочу вести список созданных объектов, поэтому я хотел бы сделать что-то вроде этого:

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 ]

3 голосов
/ 23 июня 2011

Я считаю, что лучше, когда кто-то позаботится о официантах, но ваш код в порядке.Объекты могут сделать это, нет никаких технических препятствий, которые могли бы этому помешать.Некоторые классы из стандартной библиотеки уже делают что-то подобное, например 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];
}
2 голосов
/ 23 июня 2011

Объект не может самоубийства.Он может быть либо убит вами (код, который вы послали, чтобы убить его), либо профессиональным убийцей NSAutoreleasePool.Если вы владеете им, вы должны убить его.

Предупреждение: Если оно не умрет вовремя, население увеличится и испортит память.

; -)

1 голос
/ 23 июня 2011

В некоторых случаях [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)
}

Я думаю, поскольку вышеприведенное работает нормально, у вас не должно быть никаких проблем, хотя это не так.кажется очень чистым решением.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...