Obj-C: функции C, объявленные внутри или вне блока @implementation, в чем разница? - PullRequest
7 голосов
/ 22 июня 2009

В чем разница между функцией C (статической или нет), объявленной внутри или вне блока реализации (@implementation ... @end) класса Objective-C?

это особенно верно?:

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

@implementation OblateSphereoid

void drawEggThunk (DrawingContext *context, Rect areaToDraw, void *userData)
{
BWOblateSphereoid *dealie = (BWOblateSphereoid *)userData;
dealie->_frognatz = [NSColor plaidColor];
// and more stuff.
} // drawEggThunk

...
@end // OblateSphereoid

Могу ли я получить доступ к переменным экземпляра моего класса в функциях (объявленных в том же классе) таким образом?

Ответы [ 2 ]

2 голосов
/ 23 июня 2009

Хотя это законно, я не понимаю, почему это требуется в описанном вами случае (и это уродливое решение). Почему ты не можешь просто позвонить:

[dealie setFrognatz:[NSColor plaidColor]];

Если вы обычно не предоставляете -setFrognatz:, просто сделайте его закрытым методом, объявив его внутри .m, но выше определения этой функции. (На самом деле не имеет значения, находится ли он в блоке @implementation в этом случае.)

@interface BWOblateSphereoid ()
- (void)setFrognatz:(NSColor *)acolor
@end

@implementation OblateSphereoid

void drawEggThunk (DrawingContext *context, Rect areaToDraw, void *userData)
{
    BWOblateSphereoid *dealie = (BWOblateSphereoid *)userData;
    [dealie setFrognatz:[NSColor plaidColor]];
    // and more stuff.
} // drawEggThunk

...
@end // OblateSphereoid

Есть несколько мест, где запись -> может быть полезна. Наиболее критичным является реализация -copyWithZone:, когда это может быть абсолютно обязательным (требование, которое действительно подчеркивает, почему я ненавижу любой код ObjC, который воспроизводит необработанную память, как NSCopyObject()). Но я рекомендую против -> в большинстве случаев по тем же причинам, по которым я всегда рекомендую средства доступа. Даже в том случае, когда вам нужно передать ivar по ссылке на функцию C (другое распространенное использование ->), я предпочитаю использовать временный, а затем назначать его позже.

Я считаю, что ивары по умолчанию не являются @private ошибкой в ​​ObjC .... Я поставил @private в верхней части каждого @interface блока и таким образом избежал нескольких неприятных ошибок.

Кстати, ваше решение в том виде, в котором оно написано, может быть утечкой NSColor. Может быть, это может быть, а может и нет, но определитель доступа будет уверен.

2 голосов
/ 22 июня 2009

Это будет хорошо работать, если оно внутри вашей @implementation. Я бы порекомендовал вам сделать это нормальным методом, но он работает.

Если вы исключите его из своей реализации, вы получите следующее предупреждение: Предупреждение: переменная экземпляра '' является @protected; это будет серьезной ошибкой в ​​будущем. Вы можете избежать этой ошибки, поместив @public перед вашим iVar в заголовке ... вот так:

@public 
int myInt;

Это позволяет вам обращаться к переменным, таким как структура C (указатель), где бы ни появлялся объект без предупреждения.

Так что это выполнимо, хотя не рекомендуется !!!

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