Прервите вызов метода в Objective C

Писк свободен. Cincom имеет некоммерческую версию VisualWorks. GemStone/S свободен для маленьких установок. GNU Smalltalk "свободен" в смысле GPL.

18
задан luvieere 24 October 2009 в 17:29
поделиться

8 ответов

Вы делаете это, изменяя вызов метода. Предполагая, что вы хотите получить все выпуски в NSTableView:

static IMP gOriginalRelease = nil;
static void newNSTableViewRelease(id self, SEL releaseSelector, ...) {
   NSLog(@"Release called on an NSTableView");
   gOriginalRelease(self, releaseSelector);
}


  //Then somewhere do this:
  gOriginalRelease = class_replaceMethod([NSTableView class], @selector(release), newNSTableViewRelease, "v@:");

Вы можете получить более подробную информацию в документации Objective C runtime .

23
ответ дан 30 November 2019 в 06:02
поделиться

Перехват вызовов методов в Objective-C (при условии, что это вызов Objective-C, а не C) выполняется с помощью техники, называемой swizzling.

Вы можете найти введение о том, как реализовать это здесь . В качестве примера реализации смены методов в реальном проекте см. OCMock (инфраструктура изоляции для Objective-C).

15
ответ дан 30 November 2019 в 06:02
поделиться

Вы можете заменить вызов метода одним из ваших собственных, который сделает все, что вы хотите, с «перехватом» и вызовет исходную реализацию. Swizzling выполняется с помощью class_replaceMethod ().

1
ответ дан 30 November 2019 в 06:02
поделиться

Вызов метода, нет. Сообщение отправлено, да, но вам придется быть более наглядным, если вы хотите получить хороший ответ о том, как.

0
ответ дан 30 November 2019 в 06:02
поделиться

Чтобы что-то сделать при вызове метода, вы можете попробовать подход, основанный на событиях. Поэтому, когда метод вызывается, он передает событие, которое улавливают любые слушатели. Я не очень хорошо разбираюсь в объективе C, но я только что придумал нечто подобное, используя NSNotificationCenter в Какао.

Но если под «перехватом» вы подразумеваете «стоп», тогда, возможно, вам понадобится больше логики, чтобы решить, следует ли вообще вызывать метод.

-1
ответ дан 30 November 2019 в 06:02
поделиться

Возможно, вам нужен метод -forwardInvocation NSObject . Это позволяет захватить сообщение, перенаправить его и затем повторно отправить.

1
ответ дан 30 November 2019 в 06:02
поделиться

Отправка сообщения в Objective-C транслируется в вызов функции objc_msgSend (получатель, селектор, аргументы) или один из его вариантов objc_msgSendSuper , objc_msgSend_stret , objc_msgSendSuper_stret Если это было возможно, изменить реализацию. [1216999]. из этих функций мы могли перехватить любое сообщение. К сожалению, objc_msgSend является частью среды выполнения Objective-C и не может быть переопределен.

Путем поиска я нашел в Google Книгах статью: Отражательная архитектура для приложений управления процессами, написанная Шарлоттой Пии Лунау . В документе описывается прием, заключающийся в перенаправлении указателя класса объекта isa на экземпляр настраиваемого класса MetaObject. Таким образом, сообщения, предназначенные для измененного объекта, отправляются в экземпляр MetaObject. Поскольку у класса MetaObject нет собственных методов, он может затем ответить на прямой вызов, переадресовав сообщение измененному объекту.

В документ не включены интересные фрагменты исходного кода, и я не знаю, есть ли такие подход будет иметь побочные эффекты в Какао. Но было бы интересно попробовать.

В документе описывается прием, заключающийся в перенаправлении указателя класса объекта isa на экземпляр настраиваемого класса MetaObject. Таким образом, сообщения, предназначенные для измененного объекта, отправляются в экземпляр MetaObject. Поскольку у класса MetaObject нет собственных методов, он может затем ответить на прямой вызов, переадресовав сообщение измененному объекту.

В документ не включены интересные фрагменты исходного кода, и я не знаю, есть ли такие подход будет иметь побочные эффекты в Какао. Но было бы интересно попробовать.

В документе описывается прием, заключающийся в перенаправлении указателя класса объекта isa на экземпляр настраиваемого класса MetaObject. Таким образом, сообщения, предназначенные для измененного объекта, отправляются в экземпляр MetaObject. Поскольку у класса MetaObject нет собственных методов, он может затем ответить на прямой вызов, переадресовав сообщение измененному объекту.

В документ не включены интересные фрагменты исходного кода, и я не знаю, есть ли такие подход будет иметь побочные эффекты в Какао. Но было бы интересно попробовать.

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

Документ не включает интересные части исходного кода, и я понятия не имею, будет ли такой подход иметь побочные эффекты в Какао. Но было бы интересно попробовать.

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

Документ не включает интересные фрагменты исходного кода, и я понятия не имею, будет ли такой подход иметь побочные эффекты в Какао. Но было бы интересно попробовать.

11
ответ дан 30 November 2019 в 06:02
поделиться

Создайте подкласс NSProxy и реализуйте -forwardInvocation: и -methodSignatureForSelector: (или -forwardingTargetForSelector: , если вы просто направляете его на второй объект вместо того, чтобы возиться с методом самостоятельно).

NSProxy - это класс, разработанный для реализации -forwardInvocation: в. У него есть несколько методов, но в большинстве случаев вы не хотите, чтобы их поймали. Например, перехват методов подсчета ссылок предотвратит освобождение прокси-сервера, кроме как при сборке мусора. Но если в NSProxy есть определенные методы, которые вам абсолютно необходимо пересылать, вы можете специально переопределить этот метод и вызвать -forwardInvocation: вручную. Обратите внимание на то, что тот факт, что метод указан в документации NSProxy , не означает, что NSProxy реализует его, просто ожидается, что он есть у всех прокси-объектов.

Если это не сработает для вас, опишите дополнительную информацию о вашей ситуации.

2
ответ дан 30 November 2019 в 06:02
поделиться