Насколько хорошо использовать extern в Objective C? Это делает кодирование для некоторых частей легким.. но разве это не портят ориентацию объекта?
Использование extern в Objective C
Ответ 1
Вы обнаружите, что extern
широко используется в рамках Cocoa, и трудно было бы найти убедительный аргумент, что их OO "испорчено". Напротив, Cocoa хорошо инкапсулирован и только раскрывает то, что он должен, часто через extern. Определенные глобально константы, безусловно, являются наиболее распространенным использованием, но не обязательно единственным действительным использованием.
IMO, используя extern
, не обязательно "портят" ориентацию объекта. Даже в OO часто используются переменные, доступные из любого места. Использование extern
является наиболее частым обходным решением для отсутствия "переменных класса" (например, объявленных с помощью static
в Java) в Objective-C. Это позволяет расширить область, в которой вы можете ссылаться на символ за пределами блока компиляции, где он объявлен, по существу, пообещав, что он будет где-то кем-то определен.
Вы также можете объединить extern
с __attribute__((visibility("hidden")))
, чтобы создать символ, который можно использовать вне его единицы компиляции, но не вне его узла связывания, так сказать. Я использовал это для специального кода библиотеки и фреймворка, чтобы правильно инкапсулировать внутренние детали более высокого уровня.
Ответ 2
В ключе extern
есть несколько вариантов использования в Objective-C.
Aaron Hillegass предлагает создать глобальные имена уведомлений extern.
например:.
extern NSString* const XYYourNotification;
Затем вы определяете фактическую NSString*
в своей реализации
Ответ 3
Это зависит от того, для чего вы его используете.
Совершенно верно использовать его для доступа к глобально определенным константам.
Однако, если у вас есть глобальный объект, я бы предложил использовать Singleton.
Ответ 4
В зависимости от вашей потребности, например, у вас есть страница входа. После входа в систему вы сообщаете на другие страницы в приложениях.
#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];
}
Стороне, получающей уведомление, не нужно знать значение константы.
Ответ 5
Еще один пример проблемы, когда не используется extern
:
Скажем, у вас есть глобальная переменная в заголовочном файле:
NSString *globalVar = @"Wonderful";
И вы используете его в 3 местах, импортируя этот заголовочный файл. Ваш код не будет компилироваться, компоновщик жалуется, что в вашем коде определены 3 повторяющихся символа. Для ее решения у вас есть два выхода:
Используйте static
, в этом случае для каждого файла, импортирующего этот заголовок, будет определена отдельная ссылка (и изменение одной строки не повлияет на другие строки, импортированные в другие файлы):
static NSString *globalVar = @"Wonderful";
Используйте extern
в .h файле и определите его в .m файле. Таким образом, будет определена только одна ссылка, и каждый файл будет использовать эту же ссылку (изменения отражаются во всех файлах):
extern NSString *globalVar; // in .h
NSString *globalVar = @"Wonderful"; // in .m
Выберите подход, который подходит лучше всего.