Использование переменных-членов указателя функции в классе Objective-C

(Новичок в Objective-C, но хорошо разбирается в C/C++).

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

Я не уверен, как настроить доступ к указанным указателям функций.

Решение, которое я сейчас вижу, состоит в том, чтобы объявить указанные указатели функций @public, что, как я понимаю, позволит мне вызывать их с помощью оператора ->. Это кажется мне довольно неудовлетворительным, так как указатели на функции оставлены открытыми для вмешательства, и это бросает вызов правильному ООП.

Моя следующая склонность к использованию @property и объявлению их только для чтения. Это кажется более разумным. Я предполагаю, что я бы назвал их с помощью оператора точки, поскольку идея использования to getter для получения указателя функции и последующего вызова кажется совершенно нелепой.

Можно ли использовать указатели функций в качестве свойств? Если да, то как мне объявить их свойствами:

void (*sort)(SET, int) ;
char *(*toASCII)(CARD) ;

У меня такое чувство, что я упускаю небольшой нюанс в объявлении их как свойств.


person John Carter    schedule 27.09.2010    source источник


Ответы (2)


Я считаю, что вы должны иметь возможность использовать указатели функций в качестве свойств. Вы бы сделали это так:

@property (nonatomic, readonly) char *(*toASCII)(CARD);

И затем в вашей реализации:

@synthesize toASCII;

Затем

object.toASCII();
person jtbandes    schedule 27.09.2010
comment
Спасибо, выглядит хорошо. Любая конкретная причина для неатомарности? Я предполагаю, что это потому, что это только для чтения, и мне не нужно беспокоиться о потерянных обновлениях. Если я правильно понимаю, это должно работать лучше, чем если бы оно было оставлено атомарным. - person John Carter; 27.09.2010
comment
Насколько я понимаю, атомарные и неатомарные не имеют значения при использовании свойств только для чтения. А для указателей и скаляров неатомарные и атомарные методы доступа в любом случае одинаковы (запись указателя или 32-битного значения является атомарной, поскольку выполняется одна инструкция процессора). Однако, как правило, неатомарные методы доступа работают лучше, чем атомарные, потому что требуется больше усилий для блокировки и т. д., необходимых для создания атомарного метода доступа. - person Jacques; 27.09.2010
comment
@JohnCarter nonatomic стал де-факто значением по умолчанию для свойств в Objective-C. Когда были придуманы свойства Obj-C, предполагалось, что многопоточность будет становиться все более популярной, а пометка кода как явно «поточно-небезопасного» (nonatomic) оставит код по умолчанию (atomic) более безопасным, хотя и медленным. На самом деле многопоточность в одном и том же приложении не прижилась, как они думали, и многие приложения в основном написаны с использованием отдельных потоков для совершенно разных целей, с безопасным для потоков «барьерным» кодом (мостами) между ними. TL;DR: Это nonatomic b/c большинство Obj-C, или, по крайней мере, начинается как неатом. - person Slipp D. Thompson; 17.02.2015

В вашем @интерфейсе:

@property(readonly) void (*sort)(SET, int);
@property(readonly) char *(*toASCII)(CARD);

В вашей @implementation:

@synthesize sort, toASCII;

В вашем методе инициализации (или где-либо еще, где вы хотите установить указатели функций):

sort = someFunction;
toASCII = someFunction;

В современных версиях iOS вам даже не нужно добавлять ivar (он добавляется автоматически, когда вы делаете @synthesize).

person Jacques    schedule 27.09.2010
comment
Спасибо за совет не добавлять переменные экземпляра, так все выглядит немного лучше. - person John Carter; 27.09.2010