Как назвать Метод Objective C из Метода C?

Стек , Когда Вы вызываете функцию, аргументы той функции плюс некоторые другие издержки помещаются на стек. Некоторая информация (такой как, где пойти на возврат) также хранится там. Когда Вы объявляете переменную в своей функции, та переменная также выделяется на стеке.

Освобождение стека довольно просто, потому что Вы всегда освобождаете в обратном порядке, в котором Вы выделяете. Материал стека добавляется, поскольку Вы вводите функции, соответствующие данные удалены, поскольку Вы выходите из них. Это означает, что Вы склонны оставаться в небольшом регионе стека, если Вы не вызываете много функций, которые вызывают много других функций (или создают рекурсивное решение).

"куча" "куча" является родовым названием для того, куда Вы помещаете данные, которые Вы создаете на лету. Если Вы не будете знать, сколько космических кораблей Ваша программа собирается создать, Вы, вероятно, будете использовать новое (или malloc или эквивалентный) оператор для создания каждого космического корабля. Это выделение собирается слоняться поблизости некоторое время, таким образом, вероятно, что мы освободим вещи в другом порядке, чем мы создали их.

Таким образом, "куча" намного более сложна, потому что заканчивают тем, что были регионы памяти, которые являются не использованы чередованный с блоками, которые являются - память фрагментируется. Нахождение свободной памяти размера, в котором Вы нуждаетесь, является трудной проблемой. Поэтому "кучи" нужно избежать (хотя она все еще часто используется).

Реализация Реализация и стека и "кучи" обычно до времени выполнения / ОС. Часто игры и другие приложения, которые являются очень важной производительностью, создают свои собственные решения для памяти, которые захватывают большой блок памяти от "кучи" и затем подают ее внутренне, чтобы не полагаться на ОС для памяти.

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

Физическое местоположение в памяти Это менее релевантно, чем Вы думаете из-за технологии, названной Виртуальная память , который заставляет Вашу программу думать, что у Вас есть доступ к определенному адресу, где физические данные где-то в другом месте (даже на жестком диске!). Адреса, которые Вы получаете для стека, находятся в увеличивающемся порядке, поскольку Ваше дерево вызова становится глубже. Адреса для "кучи" непредсказуемы (т.е. конкретная реализация) и откровенно не важные.

38
задан Dave Gallagher 14 August 2009 в 20:28
поделиться

5 ответов

Для того, чтобы это работало, вы должны определить метод C следующим образом:

void cMethod(id param);

и когда вы его вызовете, назовите его так:

cMethod(self);

тогда вы сможете напишите:

[param objcMethod];

В вашем cMethod .

Это потому, что переменная self является специальным параметром, который автоматически передается методам Objective-C. Поскольку методы C не пользуются этой привилегией, если вы хотите использовать self , вам придется отправить его самостоятельно.

Подробнее см. В разделе Реализация метода руководства по программированию .

50
ответ дан 27 November 2019 в 03:18
поделиться

Функция C не находится «внутри объекта self ». На самом деле, ничего нет.

Методы Objective-C фактически получают self в качестве неявного аргумента, а магия выполняется под капотом. Для простых функций C они не связаны с каким-либо классом или объектом, и здесь нет магии вызова, поэтому нет self . Если он вам нужен, вам нужно явно передать его вашей функции C в качестве аргумента.

10
ответ дан 27 November 2019 в 03:18
поделиться

Честно говоря, не существует такой вещи, как C метод. C имеет функции. Чтобы проиллюстрировать разницу, посмотрите следующие примеры:

Это рабочая программа на C, которая определяет тип и две связанные с ним функции:

#include <stdio.h>

typedef struct foo_t {
    int age;
    char *name;
} Foo;

void multiply_age_by_factor(int factor, Foo *f) {
    f->age = f->age * factor;
}

void print_foo_description(Foo f) {
    printf("age: %i, name: %s\n", f.age, f.name);
}

int main() {
    Foo jon;
    jon.age = 17;
    jon.name = "Jon Sterling";

    print_foo_description(jon);
    multiply_age_by_factor(2, &jon);
    print_foo_description(jon);

    return 0;
}

Вот реализация этой программы в Objective-C:

#import <Foundation/Foundation.h>

@interface Foo : NSObject {
    NSUInteger age;
    NSString *name;
}

@property (nonatomic, readwrite) NSUInteger age;
@property (nonatomic, copy) NSString *name;

- (void)multiplyAgeByFactor:(NSUInteger)factor;
- (NSString *)description;
- (void)logDescription;

@end


@implementation Foo 
@synthesize age;
@synthesize name;

- (void)multiplyAgeByFactor:(NSUInteger)factor {
    [self setAge:([self age] * factor)];
}

- (NSString *)description {
    return [NSString stringWithFormat:@"age: %i, name: %@\n", [self age], [self name]];
}

- (void)logDescription {
    NSLog(@"%@",[self description]);
}

@end


int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    Foo *jon = [[[Foo alloc] init] autorelease];
    [jon setAge:17];
    [jon setName:@"Jon Sterling"];

    [jon logDescription];
    [jon multiplyAgeByFactor:2];
    [jon logDescription];

    [pool drain];

    return 0;
}

Результатом чистой программы на C было:

age: 17, name: Jon Sterling
age: 34, name: Jon Sterling

Результатом программы Objective-C было:

2009-08-25 17:40:52.818 test[8963:613] age: 17, name: Jon Sterling
2009-08-25 17:40:52.828 test[8963:613] age: 34, name: Jon Sterling

Единственное различие - весь мусор, который NSLog помещает перед текстом. Функциональность точно такая же. Итак, в C вы можете использовать что-то вроде методов, но на самом деле это просто функции, которые включают указатель на структуру.

Я не думаю, что это ответило на ваш исходный вопрос, но это прояснило некоторые проблемы с терминологией похоже, у вас были.

2009-08-25 17:40:52.818 test[8963:613] age: 17, name: Jon Sterling
2009-08-25 17:40:52.828 test[8963:613] age: 34, name: Jon Sterling

Единственная разница - весь мусор, который NSLog помещает перед текстом. Функциональность точно такая же. Итак, в C вы можете использовать что-то вроде методов, но на самом деле это просто функции, которые включают указатель на структуру.

Я не думаю, что это ответило на ваш исходный вопрос, но это прояснило некоторые проблемы с терминологией похоже, у вас были.

2009-08-25 17:40:52.818 test[8963:613] age: 17, name: Jon Sterling
2009-08-25 17:40:52.828 test[8963:613] age: 34, name: Jon Sterling

Единственная разница - весь мусор, который NSLog помещает перед текстом. Функциональность точно такая же. Итак, в C вы можете использовать что-то вроде методов, но на самом деле это просто функции, которые включают указатель на структуру.

Я не думаю, что это ответило на ваш исходный вопрос, но это прояснило некоторые проблемы с терминологией похоже, у вас были.

5
ответ дан 27 November 2019 в 03:18
поделиться

Я знаю, что Aviad уже ответил на ваш вопрос, но просто чтобы добавить информацию, поскольку это не имеет отношения:

В моем случае мне нужно было вызвать метод Objective-C из C функция, которую я сам не называл (функция Carbon Event, запускаемая при регистрации глобального события горячей клавиши), поэтому передача self в качестве параметра была невозможна. В этом конкретном случае вы можете сделать это:

Определите переменную класса в своей реализации:

id thisClass;

Затем в вашем методе инициализации установите для нее значение self:

thisClass = self;

Затем вы можете вызывать методы Objective-C из любой функции C в класс без необходимости передавать self в качестве параметра функции:

void cMethod([some parameters]) {
    [thisClass thisIsAnObjCMethod];
}
25
ответ дан 27 November 2019 в 03:18
поделиться

Другой вариант ответов, приведенных до сих пор, - использовать функцию objc_msgSend () , предоставляемую средой выполнения Objective-C.

2
ответ дан 27 November 2019 в 03:18
поделиться
Другие вопросы по тегам:

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