[Закрываются] скрытые функции Objective C

12
задан 6 revs, 3 users 91% 16 July 2010 в 02:58
поделиться

8 ответов

Изложение

Objective C разрешает класс к [1 111] полностью замена другой класс в рамках приложения. Класс замены, как говорят, "изображает из себя" целевой класс. Все сообщения, отправленные в целевой класс, тогда вместо этого получены классом изложения. Существуют некоторые ограничения, на которых могут позировать классы:

  • класс А может только изобразить из себя один из своих прямых или косвенных суперклассов
  • , класс изложения не должен определять новые переменные экземпляра, которые отсутствуют в целевом классе (хотя он может определить или переопределенные методы).
  • Никакие сообщения, должно быть, не были отправлены в целевой класс до изложения.

Изложение, так же к категориям, позволяет глобально увеличивающиеся существующие классы . Изложение разрешает две функции, отсутствующие в категориях:

  • класс изложения А может назвать переопределенные методы через супер, таким образом включив реализацию целевого класса.
  • класс изложения А может переопределить методы, определенные в категориях.

пример:

@interface CustomNSApplication : NSApplication
@end

@implementation CustomNSApplication
- (void) setMainMenu: (NSMenu*) menu
{
     // do something with menu
}
@end

class_poseAs ([CustomNSApplication class], [NSApplication class]);

Это прерывает каждый вызов setMainMenu к NSApplication.

16
ответ дан 2 December 2019 в 02:51
поделиться

Метод Swizzling

В основном, во времени выполнения можно выгрузить одну реализацию метода с другим.

Вот объяснение с кодом.

Один умный вариант использования для ленивой загрузки совместно используемого ресурса: обычно Вы реализовывали бы sharedFoo метод путем получения блокировки, создания foo в случае необходимости, получения ее адреса, выпуска блокировки, затем возврата foo. Это гарантирует, что эти foo только создается однажды, но каждый последующий доступ напрасно тратит время с блокировкой, которая больше не необходима.

С методом swizzling, можно сделать, то же как прежде, кроме однажды эти foo было создано, используйте swizzling для выгрузки начального внедрения sharedFoo со вторым, которое не делает никаких проверок и просто возвращается foo, что мы теперь знаем, был создан!

, Конечно, метод swizzling может получить Вас в проблему, и могут быть ситуации, где вышеупомянутым примером является плохая идея, но эй... вот почему это скрытое функция.

20
ответ дан 2 December 2019 в 02:51
поделиться

Объектная Передача/Метод, отсутствующая

, Когда объект отправляется сообщение, для которого это не имеет никакого метода, система во время выполнения дает ему другой шанс обработать вызов перед отказом. Если поддержка объектов - вперед:: метод, время выполнения называет этот метод, передавая его информация о необработанном вызове. Возвращаемое значение от переадресованного вызова распространено назад исходной вызывающей стороне метода.

-(retval_t)forward:(SEL)sel :(arglist_t)args {
  if ([myDelegate respondsTo:sel])
 return [myDelegate performv:sel :args]
 else
 return [super forward:sel :args];
 }

Содержание от Ссылка Кармана Objective C

Это очень мощно и используется в большой степени в сообществе Ruby для различного DSLs и направляющих, и т.д. Порожденных в Smalltalk, который влиял и на Objective C и на Ruby.

15
ответ дан 2 December 2019 в 02:51
поделиться

Переключение ISA

Должен переопределить все поведения объекта? Можно на самом деле изменить класс активного объекта с одной строкой кода:

obj->isa = [NewClass class];

Это только изменяет класс, который получает вызовы метода того объекта; это не изменяет расположение объекта в памяти. Таким образом это только действительно полезно, когда у Вас есть ряд классов с тем же ivars (или один с подмножеством других), и Вы хотите переключиться между ними.

Одна часть кода я записал использование это для ленивой загрузки: это выделяет объект класса A, заливки пара критического ivars (в этом случае, главным образом рекордное число) и переключатели isa указатель для указания на LazyA. Когда любой метод кроме очень маленького набора как release и retain назван, LazyA загрузки все данные из диска, заканчивают заполнять ivars, переключаются isa указатель назад на A, и переводит вызов к реальному классу.

11
ответ дан 2 December 2019 в 02:51
поделиться
#include <Foundation/Debug.h>

Партии инструментов для попытки разыскать утечки памяти, преждевременный deallocs, и больше в том заголовочном файле.

10
ответ дан 2 December 2019 в 02:51
поделиться

Категории

Используя Категории, можно добавить методы к встроенным классам без разделения на подклассы. Полная ссылка.

Хорошо добавить удобные методы для наиболее часто используемых классов, таких как NSString или NSData.

10
ответ дан 2 December 2019 в 02:51
поделиться

Ссылка Времени выполнения Objective C

легко забыть, что синтаксический сахар Objective C преобразовывается в нормальные вызовы функции C, которые являются Объектным-C Временем выполнения. Вероятно, что Вы никогда не должны будете на самом деле копаться в и использовать что-либо во времени выполнения. Именно поэтому я считал бы это 'скрытой функцией'.

Позволяют мне дать способ, которым можно было бы использовать систему во время выполнения.

Скажем, что кто-то разрабатывает внешний API платформы, который будет использоваться третьими лицами. И это, кто-то разрабатывает класс в платформе, которая абстрактно представляет пакет данных, мы назовем их MLAbstractDataPacket. Теперь это до приложения, кто связывается в платформе, чтобы разделить на подклассы MLAbstractDataPacket и определить пакеты данных подкласса. Каждый подкласс должен переопределить метод +(BOOL)isMyKindOfDataPacket:(NSData *)data.

С той информацией в памяти...

было бы хорошо, если бы MLAbstractDataPacket обеспечил удобный метод, который возвратил корректный инициализированный класс для пакета данных, которые прибывают в форму +(id)initWithDataPacket:(NSData *)data.

здесь существует только одна проблема. Суперкласс не знает ни об одном из своих подклассов. Таким образом, здесь Вы могли использовать метод во время выполнения objc_getClassList() наряду с objc_getSuperclass() для нахождения классов, которые являются подклассами MLAbstractDataPacket. Как только у Вас есть список подклассов, можно тогда попробовать +isMyKindOfDataPacket: на каждом, пока каждый не найден или не найден.

справочная информация об этом может быть найдена в http://developer.apple.com/documentation/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html .

4
ответ дан 2 December 2019 в 02:51
поделиться

Мне нравится подробный метод, называющий как [myArray writeToFile:myPath atomically:YES], где каждый аргумент имеет маркировку.

0
ответ дан 2 December 2019 в 02:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: