Все они выполняют одну и ту же задачу, то есть метод doStuff
в anObject
выполняется синхронно в потоке current :
// 1
[anObject doStuff];
// 2
[anObject performSelector:@selector(doStuff)];
// 3
objc_msgSend(anObject, @selector(doStuff));
// 4
IMP imp = [anObject methodForSelector:@selector(doStuff)];
imp(anObject, @selector(doStuff));
- Это то, как вы обычно должны делать вещи.
- Для динамической отправки сообщения. Используйте, если селектор неизвестен или предоставлен клиентом, например, если вы реализуете шаблон target-action. или если класс
anObject
неизвестен, обычно используется, сначала спрашивая, есть ли у объекта метод с -[NSObject respondsToSelector:]
.
- Это то, к чему фактически сводится нет 1. Обычно это никогда не требуется.
- Кэширует фактическую
IMP
(реализацию) для метода, а затем вызывает его напрямую. Иногда может быть быстрее, чем 1., если используется в тесной петле. Просто помни; преждевременная оптимизация - зло .
Что вам нужно понять, так это то, что в Objective-C методы важнее, чем классы / интерфейсы. Обычно вы не запрашиваете объект, принадлежит ли он определенному классу или соответствует какому-либо протоколу, на который компилятор может пожаловаться. Во время выполнения вы вместо этого запрашиваете конкретные методы.
Короче говоря: Неважно, кто вы, только то, что вы можете сделать.
Для удобства NSObject
также имеет несколько братьев и сестер для performSelector
, которые являются асинхронными. В частности:
performSelector:withObject:afterDelay:
- выполнить метод в текущем потоке после задержки.
performSelectorInBackground:withObject:
- выполнить метод в новом фоновом потоке.
performSelectorOnMainThread:withObject:waitUntilDone:
- выполнить метод в главном потоке.
performSelector:onThread:withObject:waitUntilDone:
- выполнить метод в любом потоке.
Все асинхронные исполнители зависят от NSRunLoop
. Это не то, о чем вам нужно беспокоиться, если вы сами не создадите поток. Если вы это сделаете, то вам также нужно запустить цикл запуска новых потоков. Просто пропустите это сейчас.