Писк свободен. Cincom имеет некоммерческую версию VisualWorks. GemStone/S свободен для маленьких установок. GNU Smalltalk "свободен" в смысле GPL.
Вы делаете это, изменяя вызов метода. Предполагая, что вы хотите получить все выпуски в 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 .
Перехват вызовов методов в Objective-C (при условии, что это вызов Objective-C, а не C) выполняется с помощью техники, называемой swizzling.
Вы можете найти введение о том, как реализовать это здесь . В качестве примера реализации смены методов в реальном проекте см. OCMock (инфраструктура изоляции для Objective-C).
Вы можете заменить вызов метода одним из ваших собственных, который сделает все, что вы хотите, с «перехватом» и вызовет исходную реализацию. Swizzling выполняется с помощью class_replaceMethod ().
Вызов метода, нет. Сообщение отправлено, да, но вам придется быть более наглядным, если вы хотите получить хороший ответ о том, как.
Чтобы что-то сделать при вызове метода, вы можете попробовать подход, основанный на событиях. Поэтому, когда метод вызывается, он передает событие, которое улавливают любые слушатели. Я не очень хорошо разбираюсь в объективе C, но я только что придумал нечто подобное, используя NSNotificationCenter в Какао.
Но если под «перехватом» вы подразумеваете «стоп», тогда, возможно, вам понадобится больше логики, чтобы решить, следует ли вообще вызывать метод.
Возможно, вам нужен метод -forwardInvocation
NSObject
. Это позволяет захватить сообщение, перенаправить его и затем повторно отправить.
Отправка сообщения в 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 нет собственных методов, он может затем ответить на прямой вызов, переадресовав сообщение измененному объекту.
В документ не включены интересные фрагменты исходного кода, и я не знаю, есть ли такие подход будет иметь побочные эффекты в Какао. Но было бы интересно попробовать.
затем он может ответить на прямой вызов, переадресовав сообщение измененному объекту.Документ не включает интересные части исходного кода, и я понятия не имею, будет ли такой подход иметь побочные эффекты в Какао. Но было бы интересно попробовать.
затем он может ответить на прямой вызов, переадресовав сообщение измененному объекту.Документ не включает интересные фрагменты исходного кода, и я понятия не имею, будет ли такой подход иметь побочные эффекты в Какао. Но было бы интересно попробовать.
Создайте подкласс NSProxy
и реализуйте -forwardInvocation:
и -methodSignatureForSelector:
(или -forwardingTargetForSelector:
, если вы просто направляете его на второй объект вместо того, чтобы возиться с методом самостоятельно).
NSProxy
- это класс, разработанный для реализации -forwardInvocation:
в. У него есть несколько методов, но в большинстве случаев вы не хотите, чтобы их поймали. Например, перехват методов подсчета ссылок предотвратит освобождение прокси-сервера, кроме как при сборке мусора. Но если в NSProxy
есть определенные методы, которые вам абсолютно необходимо пересылать, вы можете специально переопределить этот метод и вызвать -forwardInvocation:
вручную. Обратите внимание на то, что тот факт, что метод указан в документации NSProxy
, не означает, что NSProxy
реализует его, просто ожидается, что он есть у всех прокси-объектов.
Если это не сработает для вас, опишите дополнительную информацию о вашей ситуации.