Использование собственного распределителя в библиотеке iOS - PullRequest
2 голосов
/ 16 ноября 2011

Я создаю библиотеку, которая будет использоваться несколькими типами приложений для iOS.Часть моего API позволяет пользователю определять подпрограммы, которые будут использоваться для выделения библиотеки.Моя библиотека в основном реализована на C ++, поэтому до сих пор это было просто.

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

Как я могу убедиться, что все объекты пользовательского интерфейса Какао, созданные моей библиотекой, распределены с моими собственными функциями?

Я пробовал несколько вещей, включая переопределение -initWithZone и вызов CFAllocatorSetDefault до моего -init.Никто из них еще не работал;и, честно говоря, я все еще начинающий с Objective C и Cocoa , поэтому я хотел бы знать, каков "правильный" способ сделать это.

1 Ответ

4 голосов
/ 16 ноября 2011

Сейчас я не могу найти доказательств этого, но, безусловно, это был тот случай, когда CFAllocator, malloc_zone_t и NSZone были соединены по бесплатному мосту. Так что вы можете просто привести свой распределитель к NSZone и передать его.

Я думаю, что проблема, с которой вы столкнетесь, заключается в том, что NSZone был добавлен на NextStep, чтобы позволить программе поддерживать несколько куч, с ощущением, что это позволит программистам держать связанные объекты близко друг к другу в памяти - что хорошо для кеширования - и в некоторых случаях отбрасывать целые графы объектов без обхода графа, что очевидно быстро. Тем не менее, первое не принесло пользы на практике, а второе скорее создаст проблемы, чем принесет реальную пользу. Таким образом, Apple отступила от NSZone s, постепенно превращая связанные вызовы времени выполнения в no-ops и удаляя подробную документацию. Apple считает, что на уровне Objective-C вы должны не только поддерживать только одну кучу (что является побочной проблемой с вашей точки зрения), но и они всегда будут знать, как ее поддерживать.

РЕДАКТИРОВАТЬ: альтернативная идея состоит в том, чтобы заменить alloc NSObject, который является тем, что создает память. Время выполнения Objective-C достаточно четко определено, чтобы мы точно знали, какое поведение alloc демонстрирует, так что ванильная версия может быть:

+ (id)alloc
{
    Class *newInstance;

    // we'll use calloc to ensure we get correct initial behaviour of
    // everything equal to 0, and use the runtime's class_getInstanceSize
    // so that we're allocating the correct amount of memory irrespective
    // of whether this call has fallen through from a subclass
    newInstance = (Class *)calloc(1, class_getInstanceSize(self));

    // the thing that defines a class is that the first thing stored in
    // it is the isa pointer, which points to the metaclass. So we'll
    // set the isa pointer appropriately
    *newInstance = self;

    return (id)newInstance;
}

Чтобы заменить нормальный init NSObject, вы, вероятно, захотите определить альтернативу как метод категории для NSObject с именем, скажем, customInit, а затем использовать class_getClassMethod, class_getMethodImplementation и method_setImplementation непосредственно на [NSObject class] для переключения это на место. См. Object-C Runtime Reference для документации по ним.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...