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];