Уничтожение себя изнутри себя
У меня есть класс Objective-C, экземпляры которого могут обнаруживать, когда они больше не нужны, и уничтожать себя, но я ищу безопасный способ вызвать самоуничтожение объекта изнутри самого объекта, без какого-либо "уничтожения метода, который вызывая уничтожение "... Мой код выглядит примерно так (некоторые для краткости удалены):
+ (oneway void)destroyInstance:(id)obj {
printf("Destroying.\n");
if (obj != nil) {
free(obj);
obj = nil;
}
}
- (oneway void)release {
_noLongerRequired = [self determineIfNeeded]; // BOOL retVal
if (_noLongerRequired) {
[self deallocateMemory]; // Free ivars etc (NOT oneway)
[MyClass destroyInstance:self]; // Oneway
}
}
Если я позвоню -release
, он должен немедленно вернуться к основному потоку (из-за oneway
).
Между тем, если экземпляр обнаружит, что он больше не нужен, он должен затем вызвать oneway
метод класса destroyInstance:
и удалить себя из среды выполнения. Мой вопрос, это безопасно? И использовал ли я oneway
правильно? Мне кажется, есть возможность уничтожить инстанс -release
функция до его возвращения, что может быть... довольно плохо...?
(PS: Очевидно, не ищет ничего общего с NSObject и т. Д. :)
)
1 ответ
Это, без сомнения, ужасная идея, если вы хотите работающее и поддерживаемое программное обеспечение и небезопасное практически в любом контексте. Но иногда ужасные, небезопасные идеи могут быть веселыми в выходные, поэтому я отвечу на некоторые вопросы, которые могу различить.
Метод не будет "уничтожен", потому что экземпляр освобожден. Что может случиться так self
может в конечном итоге указывать на освобожденную память во время выполнения метода, что означает, что доступ self
или любые переменные экземпляра в течение этого времени могут дать сбой.
Что касается остальной части вашего кода, нет никаких причин для установки obj
равно nil
в +destroyInstance
так что если вы пытались сделать что-то конкретное (nil
указатели на объект, возможно), это неправильный путь.
Думая об использовании oneway
Язык говорит, что отправка этого сообщения не блокирует вызывающий поток. В контексте освобождения объектов я думаю, что это имеет некоторый смысл, так как предположительно на цель сообщения больше никогда не ссылается этот поток. По этой логике я думаю, что ваша декларация +destroyInstance
может быть хорошо. Мне интересно, если вам нужно обеспечить какую-то синхронизацию, чтобы не было retain
/release
расовые условия, но если подумать об этом, захват объекта не должен быть асинхронным.
Мое личное мнение таково, что любой, кто внедряет этот код в производство, вероятно, должен быть уволен или предъявлен иск =P. Но если это только для образовательных целей, развлекайтесь и надеюсь, что это поможет.