Использование extern в Objective C - PullRequest
45 голосов
/ 22 декабря 2009

Насколько хорошо использовать extern в Objective C? Это облегчает кодирование некоторых частей ... но не портит ли ориентацию объекта?

Ответы [ 5 ]

57 голосов
/ 22 декабря 2009

Вы обнаружите, что extern широко используется в платформах Какао, и трудно найти убедительный аргумент, что их ОО "испорчен". Напротив, какао хорошо инкапсулировано и показывает только то, что должно, часто через экстерьер. Определенные глобально константы, безусловно, являются наиболее распространенным использованием, но не обязательно единственным допустимым использованием.

IMO, использование extern не обязательно «портит» ориентацию объекта. Даже в ОО часто используются переменные, которые доступны из любого места. Использование extern является наиболее частым решением проблемы отсутствия «переменных класса» (таких, которые объявлены с static в Java) в Objective-C. Это позволяет вам расширить область действия, в которой вы можете ссылаться на символ за пределами блока компиляции, где он объявлен, по сути, обещая, что он будет где-то определен кем-то.

Вы также можете комбинировать extern с __attribute__((visibility("hidden"))), чтобы создать символ, который можно использовать вне его модуля компиляции, но не, так сказать, вне его модуля связи. Я использовал это для пользовательской библиотеки и кода инфраструктуры, чтобы правильно инкапсулировать внутренние детали более высокого уровня.

16 голосов
/ 22 декабря 2009

В Objective-C есть несколько вариантов использования для ключевого слова extern.
Аарон Хиллегасс предлагает создать глобальные уведомления об именах extern. e.g.:

extern NSString* const XYYourNotification;

Затем вы определяете фактическую NSString* в вашей реализации

10 голосов
/ 22 декабря 2009

Зависит от того, для чего вы его используете. Вполне допустимо использовать его для доступа к глобально определенным константам.
Однако если у вас есть глобальный объект, я бы предложил вместо него использовать Singleton .

3 голосов
/ 19 марта 2017

Зависит от вашей потребности, например, у вас есть страница входа. После входа в систему вы уведомляете другие страницы в приложениях.

#import <Foundation/Foundation.h>

extern NSString *const DidLoginNotification;

@interface LoginViewController : NSObject
- (void)login;
@end


// LoginViewController.m
#import "LoginViewController.h"

//define extern const in implementation file only once for the whole process
NSString *const DidLoginNotification =
    @"DidLoginNotificationNotified";

@implementation LoginViewController

- (void)login {
    // Perform notification
    [[NSNotificationCenter defaultCenter];
    sendNotificationName: DidLoginNotification
                    object:nil];
}

Принимающей стороне уведомления не нужно знать значение const.

2 голосов
/ 07 июня 2018

Еще один пример проблемы, когда не используется extern:

Скажем, у вас есть глобальная переменная в заголовочном файле:

NSString *globalVar = @"Wonderful";

И вы используете его в 3 местах, импортируя этот заголовочный файл. Ваш код не будет компилироваться, компоновщик жалуется, что в вашем коде определены 3 повторяющихся символа. Для ее решения у вас есть два выхода:

Используйте static, в этом случае для каждого файла, импортирующего этот заголовок, будет определена отдельная ссылка (и изменение одной строки не повлияет на другие строки, импортированные в другие файлы):

static NSString *globalVar = @"Wonderful";

Используйте extern в файле .h и определите его в файле .m. Таким образом, будет определена только одна ссылка, и каждый файл будет использовать эту же ссылку (изменения отражаются во всех файлах):

extern NSString *globalVar; // in .h

NSString *globalVar = @"Wonderful"; // in .m

Выберите подход, который подходит лучше всего.

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