У меня есть класс TestView с переменной экземпляра «loader» типа Loader. Я создал метод в TestView для создания экземпляра загрузчика; и затем начните загружать что-то через 2 секунды.
Этот метод выглядит так:
-(void) createLoaderAndStartLoadingTwoSecondsLater{
loader = Loader();
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
printf("DISPATCHING AFTER %i seconds", i);
loader->load(*urlRequest);
});
}
В другом месте есть метод dealloc:
-(void) dealloc
{
delete loader;
}
До тех пор, пока не истечет 2-секундный таймер, возможно, что Deloloc будет вызван. В этом случае мне бы хотелось, чтобы блок dispatch_after никогда не выполнялся.
РЕДАКТИРОВАТЬ:
Я хотел бы сделать это:
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
printf("DISPATCHING AFTER %i seconds", i);
if ( !hasBeenDeleted( loader ) ){
loader->load(*urlRequest);
}
});
Но меня волнуют две вещи:
Поэтому я бы очень хотел сделать это:
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
printf("DISPATCHING AFTER %i seconds", i);
lockTheOtherThreads();
if ( !hasBeenDeleted( loader ) ){
loader->load(*urlRequest);
}
unlockTheOtherThreads();
});
Но я также не знаю, как реализовать lockTheOtherThreads ()
при условии, что у вас есть это
@implementation MyClass {
Loader *loader;
}
-(void)createLoaderAndStartLoadingTwoSecondsLater{
loader = new Loader();
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
printf("DISPATCHING AFTER %i seconds", i);
loader->load(*urlRequest);
//self->loader->load(*self->urlRequest);
});
}
Созданный вами блок отправки будет содержать сильную ссылку на self
, что значит dealloc
не будет вызван до выполнения блока.
Также используйте unique_ptr
так что вам не нужно звонить удалить. Или же shared_ptr
с atomic_load
если загрузчик может быть доступен для нескольких потоков.
@implementation MyClass {
std::unique_ptr<Loader> loader;
}
-(void)createLoaderAndStartLoadingTwoSecondsLater{
loader.reset(new Loader()); // will delete previous loader if it exist
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
printf("DISPATCHING AFTER %i seconds", i);
loader->load(*urlRequest);
});
}
// you don't need dealloc anymore
Обновить:
Вы можете поймать слабую ссылку на self
в блоке, чтобы избежать продления срока службы self
-(void)createLoaderAndStartLoadingTwoSecondsLater{
loader.reset(new Loader()); // will delete previous loader if it exist
__weak typeof(self) weakSelf = self; // a weak reference to self
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
typeof(weakSelf) strongSelf = weakSelf;
printf("DISPATCHING AFTER %i seconds", i);
if (strongSelf) { // if still alive
strongSelf->loader->load(*urlRequest);
} // else it is deallocated
});
}
Совершенно неясно, что вы на самом деле пытаетесь сделать. И вещи не просто «потокобезопасны», вам нужно сказать, что вы хотите сделать.
После вызова dealloc рассматриваемый объект исчезнет, когда dealloc вернется. Не имеет значения, если кто-то еще пытался его сохранить. И кажется, что вы смешиваете Objective-C и C ++. Когда в C ++ вызывается delete, объект исчезает.
Я предлагаю вам прочитать слабые указатели в Objective-C и держаться подальше от C ++.