Создание и освобождение объектов одним и тем же методом, при этом используя себя в качестве делегата - PullRequest
0 голосов
/ 18 июня 2010

В target-c вы несете ответственность за освобождение выделенных объектов, но что происходит, когда вы выделяете объект в методе, назначаете self в качестве делегата объектов, а затем освобождаете объект.

Обратные вызовы от вновь созданного (и освобожденного) объекта в этот момент не выполняются, или, скорее, не происходят.

- (void)doSomething
{
    MyObj *myObj = [[MyObj alloc] init];
    myObj.delegate = self;
    [myObj performOperation];
    [myObj release];
}

- (void)callbackMethodFromMyObj:(NSString *)message
{
    NSLog(message);
}

EDIT: Чтобы расширить это, возможно, важно включить, что MyObj использует NSURLConnection.

MyObj:

@implementation MyObj

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    [self.delegate callbackMethodFromMyObj:@"a string"];
}

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

Один из способов сделать это - передать объект в обратном вызове и освободить его в обратном вызове, но разве это правильный путь?

Я обновил этот пост, включив в него тот факт, что я использую NSURLConnection, поэтому здесь задействованы потоки.

Если бы я выпустил * myObj, он был бы выпущен до того, как NSURLConnection сможет вызвать - (void)connectionDidFinishLoading:(NSURLConnection *)connection

Как я вижу, и из приведенного ниже ответа кажется, что очень важно передать * myObj в качестве параметра в обратном вызове, освободив его, таким образом, внутри - (void)callbackMethodFromMyObj:(NSString *)message

и изменение сигнатуры метода, в результате чего получается следующий метод:

- (void)callbackMethodFromMyObj:(NSString *)message withMyObj:(MyObj *)sender
{
    // do things
    [myObj release];
}

1 Ответ

0 голосов
/ 20 июня 2010

Редактировать

Если вы являетесь автором класса MyObj, а точнее, если вы управляете методом, который вызывает обратный вызов callbackMethodFromMyObj:, то вы можете рассматривать MyObj как объект однократной кратковременной операции, который выпускает себя после него. вызывает его обратный вызов, то есть

/* We are inside MyObj, some internal method */
NSString* message; // Assuming

[self.delegate callbackMethodFromMyObj: message];
[self release]; // add this

Таким образом, вы не пропускаете конкретную логику, касающуюся времени жизни ваших экземпляров MyObj, в делегаты. Еще лучше, поскольку делегаты всегда являются необязательными (ну, они должны быть!), Даже если вы не предоставите делегата, MyObj будет правильно собирать мусор.

Надеюсь, это помогло.

Оригинальный ответ

Ваш пример немного сбивает с толку, но если я правильно его понимаю, вы хотите создать какой-то объект Command (скажем, MyObj, являющийся NSInvocation) и выполнить какое-то уведомление делегата с экземпляром, который его создает (например, self).

Если то, что вы делаете в executeOperation, происходит в том же потоке, что и doSomething, то вам нечего бояться, потому что обратный вызов будет вызван еще до того, как сообщение о выпуске будет отправлено.

Что сбивает с толку, так это то, что вы упоминаете ...

... что происходит, когда вы выделяете объект в методе, назначаете себя делегатом объектов и затем освобождаете объект.

Если вы выделите объект, а затем освободите его, не назначив его сначала где-то еще (например, сохраняющему свойству), тогда он будет немедленно освобожден. Он больше не существует, и ничто не ссылается на него для отправки сообщения performOperation, поэтому делегат является избыточным.

Если вы хотите удержать объект, присвойте ему сохраняемое свойство.

Чтобы сделать делегата более переносимым, я бы посоветовал, как вы уже упоминали, передать делегата (в вашем случае MyObj) в функцию обратного вызова.

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