Objective C: Как использовать управление памятью правильно для асинхронных методов

Я должен назвать метод, который запускает некоторый асинхронный код

MyClass* myClass = [[MyClass alloc] init];
[myClass startAsynchronousCode];

Теперь я не могу просто выпустить его, поскольку это вызвало бы ошибку, так как код все еще работает:

[myClass release];  // causes an error

Что лучший способ состоит в том, чтобы иметь дело с памятью?

8
задан Cœur 30 January 2019 в 03:11
поделиться

4 ответа

Вы можете - [MyClass startAsynchronousCode] вызвать обратный вызов:

typedef void(*DoneCallback)(void *);

-(void) startAsynchronousCode {
  // Lots of stuff
  if (finishedCallback) {
    finishedCallback(self);
  }
}

и затем создать экземпляр MyClass может выглядеть так:

MyClass *myClass = [[MyClass alloc] initWith: myCallback];

myCallback может выглядеть так:

void myCallback(void *userInfo) {
  MyClass *thing = (MyClass *)userInfo;
  // Do stuff
  [thing release];
}
4
ответ дан 5 December 2019 в 20:14
поделиться

Вы должны сохранить свой объект myClass внутри метода startAsynchronousCode. И отпустите его внутри тоже после того, как он закончится.

Это поведение используется в NSURLConnection, UIAlertView и других асинхронных объектах.

1
ответ дан 5 December 2019 в 20:14
поделиться

Я всегда поддерживал переменную экземпляра, указывающую на асинхронный объект.

- (id)init {
    myClass = [[MyClass alloc] init];
    [myClass startAsynchronousCode];
}

- (void)myClassDidFinish:(MyClass *)myClass {
    [myClass release];
}
0
ответ дан 5 December 2019 в 20:14
поделиться

Как дела? вызывая асинхронный код? Если вы используете NSThread + detachNewThreadSelector: toTarget: withObject: , вы обнаружите, что целевой объект сохраняется в потоке до его завершения, а затем освобождается. Таким образом, вы можете освободить объект сразу после асинхронного сообщения.

например.

@implementation MyClass

-(void) startAsynchronousCode
{
    [NSThread detachNewThreadSelector: @selector(threadMain:) toTarget: self withObject: nil];
}

-(void) threadMain: (id) anObject
{
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    // do stuff
    [pool drain];
}
@end

С приведенным выше кодом совершенно безопасен следующий код:

MyClass* myClass = [[MyClass alloc] init];
[myClass startAsynchronousCode];
[myClass release];
3
ответ дан 5 December 2019 в 20:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: