#ios #objective-c
#iOS #objective-c
Вопрос:
У меня есть класс, который принимает делегат и, конечно, вызывает методы делегата в какой-то момент времени, в этом примере NSURLConnection
:
NSURLConnection *theConnection = [[NSURLConnection alloc]
initWithRequest:request
delegate:delegate];
Я хочу перехватить didFailWithError
метод делегата, т. Е. Экземпляр NSURLConnection не вызывает метод делегата напрямую, вместо этого он вызывает другой метод, который вызывает в didFailWithError
конечном итоге.
То, что я хотел бы сделать, это что-то вроде «наследования» на объекте вместо уровня класса. Например, в javascript я бы сделал что-то вроде:
// Set the original delegate as prototype
var myDecoratedDelegate = Object.create(delegate);
// save the original method
var didFailWithError = delegate.didFailWithError;
// Decorate the didFailWithError method
myDecoratedDelegate.didFailWithError = function() {
// do something
didFailWithError()
}
var connection = new Connection(request, myDecoratedDelegate);
Таким образом, я бы заархивировал, чтобы каждый метод исходного делегата вызывался нормально, за исключением функции, которую я хотел бы украсить.
Я знаю, objective c — это не javascript, но я довольно новичок в objective c, и, возможно, есть элегантное решение.
Однако я знаю, что с method_setImplementation
помощью вас можно изменить реализацию методов экземпляров. Однако я думаю, что для вызываемого абонента было бы довольно неожиданно, если бы я изменил исходное поведение класса и предпочел бы этого не делать.
Приемлемым решением для меня также было бы наследовать NSURLConnection
класс и изменить способ, которым он вызывает своего делегата. Однако я не знаю, как это сделать, поскольку это не является частью общедоступного API класса NSURLConnection.
Комментарии:
1. «Однако я думаю, что для вызываемого абонента было бы довольно удивительно, если бы я изменил исходное поведение класса и предпочел бы этого не делать». — разве это не именно то, что вы делаете с Javascript?
2. Нет. Я использую исходный делегат в качестве прототипа для оформленного делегата, т. Е. Каждый вызов метода для оформленного делегата будет вызывать исходный делегат, если он не перезаписан в оформленном делегате.