Objective-C Language
Классы и объекты
Поиск…
Синтаксис
- Cat * cat = [[Cat alloc] init]; // Создаем объект cat типа Cat
- Dog * dog = [[Dog alloc] init]; // Создание объекта собаки типа Dog
- NSObject * someObject = [NSObject alloc]; [someObject init]; // не делаем этого
- XYZObject * object = [XYZObject new]; // Использовать new для создания объектов, если для инициализации не нужны аргументы NO
- NSString * someString = @ "Hello, World!"; // Создание NSString с литеральным синтаксисом
- NSNumber * myFloat = @ 3.14f; // Другой пример создания NSNumber с использованием литерала синтаксиса
- NSNumber * myInt = @ (84/2); // Создаем объект, используя выраженное в ядре выражение
Создание классов с значениями инициализации
#import <Foundation/Foundation.h>
@interface Car:NSObject {
NSString *CarMotorCode;
NSString *CarChassisCode;
}
- (instancetype)initWithMotorValue:(NSString *) motorCode andChassisValue:(NSInteger)chassisCode;
- (void) startCar;
- (void) stopCar;
@end
@implementation Car
- (instancetype)initWithMotorValue:(NSString *) motorCode andChassisValue:(NSInteger)chassisCode{
CarMotorCode = motorCode;
CarChassisCode = chassisCode;
return self;
}
- (void) startCar {...}
- (void) stopCar {...}
@end
Метод initWithMotorValue: type andChassisValue: type будет использоваться для инициализации объектов Car.
Singleton Class
Что такое класс Singleton?
Класс singleton возвращает тот же экземпляр, независимо от того, сколько раз приложение запрашивает его. В отличие от обычного класса, объект singleton предоставляет глобальную точку доступа к ресурсам своего класса.
Когда использовать классы Singleton?
Синглотоны используются в ситуациях, когда эта единственная точка управления желательна, например, с классами, которые предлагают некоторую общую службу или ресурс.
Как создать классы Singleton
Сначала создайте новый файл и подкласс его из NSObject . Назовите это что угодно, здесь мы будем использовать CommonClass . Теперь Xcode будет генерировать файлы CommonClass.h и CommonClass.m для вас.
В вашем файле CommonClass.h :
#import <Foundation/Foundation.h>
@interface CommonClass : NSObject {
}
+ (CommonClass *)sharedObject;
@property NSString *commonString;
@end
В вашем файле CommonClass.m :
#import "CommonClass.h"
@implementation CommonClass
+ (CommonClass *)sharedObject {
static CommonClass *sharedClass = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedClass = [[self alloc] init];
});
return sharedClass;
}
- (id)init {
if (self = [super init]) {
self.commonString = @"this is string";
}
return self;
}
@end
Как использовать классы Singleton
Класс Singleton, который мы создали ранее, будет доступен из любого места проекта, если вы импортировали файл CommonClass.h в соответствующий модуль. Чтобы изменить и получить доступ к общим данным в Singleton Class, вам придется получить доступ к общему объекту этого класса, к которому можно получить доступ, используя метод sharedObject например:
[CommonClass sharedObject]
Чтобы прочитать или изменить элементы в общем классе, выполните следующие действия:
NSString *commonString = [[CommonClass sharedObject].commonString; //Read the string in singleton class
NSString *newString = @"New String";
[CommonClass sharedObject].commonString = newString;//Modified the string in singleton class
Тип возврата «instancetype»
Objective-C поддерживает специальный тип, называемый instancetype, который может использоваться только как тип, возвращаемый методом. Он оценивает класс принимающего объекта.
Рассмотрим следующую иерархию классов:
@interface Foo : NSObject
- (instancetype)initWithString:(NSString *)string;
@end
@interface Bar : Foo
@end
Когда вызывается [[Foo alloc] initWithString:@"abc"] , компилятор может сделать вывод о том, что тип возврата Foo * . Класс Bar полученный из Foo но не переопределял объявление инициализатора. Тем не менее, благодаря instancetype , компилятор может сделать вывод, что [[Bar alloc] initWithString:@"xyz"] возвращает значение типа Bar * .
Рассмотрим тип возврата -[Foo initWithString:] являющийся Foo * вместо этого: если вы назовете [[Bar alloc] initWithString:] , компилятор сделает вывод о Foo * , а не о Bar * как и намерение разработчик. instancetype решить эту проблему.
Перед введением instancetype , инициализаторы, статические методы, такие как Singleton Accessors и другие методы, которые хотят вернуть экземпляр класса-получателя, необходимо вернуть id . Проблема в том, что id означает «объект любого типа» . Таким образом, компилятор не может обнаружить, что NSString *wrong = [[Foo alloc] initWithString:@"abc"]; присваивает переменной неправильный тип.
Из-за этой проблемы инициализаторы всегда должны использовать instancetype вместо id в качестве возвращаемого значения.
Определение обобщений
Вы можете улучшить свои собственные классы с помощью дженериков, как NSArray или NSDictionary .
@interface MyClass<__covariant T>
@property (nonnull, nonatomic, strong, readonly) NSArray<T>* allObjects;
- (void) addObject:(nonnull T)obj;
@end
Разница между распределением и инициализацией
В большинстве объектно-ориентированных языков выделение памяти для объекта и его инициализация - это атомная операция:
// Both allocates memory and calls the constructor
MyClass object = new MyClass();
В Objective-C это отдельные операции. Методы класса alloc (и его исторический allocWithZone: заставляют среду выполнения Objective-C резервировать требуемую память и очищать ее. За исключением нескольких внутренних значений, все свойства и переменные установлены в 0 / NO / nil .
Затем объект уже «действителен», но мы всегда хотим вызвать метод для фактической настройки объекта, который мы называем инициализатором . Они служат той же цели, что и конструкторы на других языках. По соглашению эти методы начинаются с init . С точки зрения языка, это обычные методы.
// Allocate memory and set all properties and variables to 0/NO/nil.
MyClass *object = [MyClass alloc];
// Initialize the object.
object = [object init];
// Shorthand:
object = [[MyClass alloc] init];