2014-02-14 2 views
1

Я хотел бы знать, как разрешить больше чем один объект в то время. Я ищу что-то вроде NSSet с 50 пустыми объектами.Alloc несколько объектов в то время

Причина в том, что я интенсивно работаю с большим количеством распределений (1.000.000), и это занимает много времени для этого на одну базу. (Метод Alloc является дорогостоящим временем).

+1

Зачем вам так много экземпляров на мобильном устройстве? – Wain

ответ

1

Чтобы ответить на ваш вопрос прямо, есть два времени выполнения функций, которые позволяют создавать/разрушать объект, расположенный в предварительно выделенном блоке памяти:

/** 
* Creates an instance of a class at the specific location provided. 
* 
* @param cls The class that you wish to allocate an instance of. 
* @param bytes The location at which to allocate an instance of \e cls. 
* Must point to at least \c class_getInstanceSize(cls) bytes of well-aligned, 
* zero-filled memory. 
*/ 
OBJC_EXPORT id objc_constructInstance(Class cls, void *bytes) 
    __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0) 
    OBJC_ARC_UNAVAILABLE; 

/** 
* Destroys an instance of a class without freeing memory and removes any 
* associated references this instance might have had. 
*/ 
OBJC_EXPORT void *objc_destructInstance(id obj) 
    __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0) 
    OBJC_ARC_UNAVAILABLE; 

Полностью тестировался пример использования (ARC должна быть отключена в файле @implementation):

+ (void)allocInPlace:(void *)buffer 
{ 
    objc_constructInstance(self, buffer); 
} 

- (void)dealloc 
{ 
    objc_destructInstance(self); 
} 

size_t instanceSize = class_getInstanceSize(MyClass.class); 

// This may not be enough, since we need to ensure that object instances are 16-byte aligned 
void *buffer = calloc(instanceSize, numObjects); 

for (size_t i = 0; i < numObjects; i++) { 
    // Need to ensure that this is 16-byte aligned 
    void *objBuffer = buffer + (instanceSize * i); 
    [mySet addObject:[[MyClass allocInPlace:objBuffer] init]]; 
} 

Вы будете урожденная d, чтобы висеть на buffer и free(), когда он больше не нужен.

Как бы то ни было, вы, возможно, должны использовать только массив C структур. Метод, который я использовал здесь, работает против стандартной практики Obj-C и подвержен ошибкам (если, например, вы освобождаете буфер до того, как все объекты были разрушены, тогда произойдет Bad Things).

+0

Спасибо за ваш ответ. Две вещи, которые я не понимаю. 1. Вы все еще используете цикл для всего объекта (numObject) и 2.если я правильно понимаю этот код. Вы создаете один объект экземпляра MyClass с большим размером, но не более объектов нормального размера. –

+0

Один блок памяти содержит много экземпляров. Если профилирование предполагает, что большое количество небольших распределений вызывает проблемы с производительностью, оно может исправить их, выполнив одно большое распределение. –

+0

(адрес, переданный каждому init, отличается из-за арифметики указателя) –

2

Существует большая статья на какао С любовью Alternative Objective-C object allocation for large arrays о выделении

+1

Описанный выше метод больше не поддерживается, так как макет объекта фактически закрыт, поскольку iOS 7 отказывается от прямого доступа 'isa'. –

+0

@ChrisDevereux - это Apple, предлагающая альтернативные способы? – sage444

+0

'objc_constructInstance (Class cls, void * bytes)' и 'objc_destructInstance (id obj)' может работать –

Смежные вопросы