Как инициализировать свойство в iOS UITableViewController

99
11

Я работаю над UITableViewController


@interface GinkgoDeliveryOrdersTableViewController : UITableViewController

@property PFQuery * query;
@property NSArray * products;

@end


Как инициализировать эти два свойства? В настоящее время я делаю ленивую инициализацию:


@implementation GinkgoDeliveryOrdersTableViewController

@synthesize query = _query;
@synthesize products = _products;

- (void) initQuery {
_query = [PFQuery queryWithClassName:@"_Product"];
}

- (void) initProducts {
if(! _query)
[self initQuery];
_products = [_query findObjects];
}


В результате, каждый раз, когда я хочу использовать эти два свойства, я должен сделать что-то вроде этого:


if(! self.products)
[self initProducts];

и


if(! self.query)
[self initQuery];

Я чувствую, что здесь что-то не так. Есть ли более чистый способ сделать это?
Большое вам спасибо!

спросил(а) 2021-01-25T21:15:17+03:00 5 месяцев назад
1
Решение
117

Если значения не устанавливаются снаружи, они не должны быть прочитаны/записывать свойства. Сделайте их доступными только для чтения и используйте ленивую загрузку в методе "getter".


@interface GinkgoDeliveryOrdersTableViewController : UITableViewController

@property (nonatomic, readonly) PFQuery * query;
@property (nonatomic, readonly) NSArray * products;

@end

@implementation GinkgoDeliveryOrdersTableViewController

@synthesize query = _query;
@synthesize products = _products;

- (PFQuery *)query {
if (!_query) {
_query = ...
}

return _query;
}

Сделайте то же самое для products getter.


Обратите внимание, что в вашем исходном коде нет необходимости в строках @synthesize, но в этом обновленном коде они нужны, потому что иначе ivar не будет автоматически сгенерирован из-за явного метода getter.

ответил(а) 2021-01-25T21:15:17+03:00 5 месяцев назад
100

При создании @property компилятор автоматически создает сеттеры и геттеры.


// Let say you create a public property in your header file (.h)
@property NSObject *var;

// You synthesize your property in your implementation file (.m)
@synthesize var = _var;

// What does the compiler creates for you?
// A getter that by default has the same name as your variable
- (NSObject *)var
{
return _var;
}

// A setter that by default is called "set" + "Var" (your variable name with first letter in uppercase)
- (void)setVar:(NSObject *)var
{
_var = var;
}


Ленивый экземпляр - это шаблон дизайна, в котором вы решили подождать до последнего момента, чтобы создать экземпляр объектов. Итак, в вашем случае это будет в getter. Когда кто-то пытается прочитать свойство, которое еще не было использовано, пришло время их создания: D


Это то, что я думаю, что вы хотите: D

// GinkgoDeliveryOrdersTableViewController.h
@interface GinkgoDeliveryOrdersTableViewController : UITableViewController

@property PFQuery *query;
@property NSArray *products;

@end

// GinkgoDeliveryOrdersTableViewController.m
@implementation GinkgoDeliveryOrdersTableViewController

@synthesize query = _query;
@synthesize products = _products;

// SETTERS
- (void)setQuery:(PFQuery *)query {
_query = query;
}

- (void)setQuery:(NSArray *)products {
_products = array;
}

// GETTERS
- (PFQuery *)query {
if (!_query)
_query = [PFQuery queryWithClassName:@"_Product"];

return _query;
}

- (NSArray *)products {
if (!_products)
_products = [_query findObjects];

return _products;
}


    @synthesize для примитивных типов выделяет пространство, необходимое для переменной.
    @synthesize для указателей на объекты выделяет пространство, необходимое только для указателя. Вы должны выделить и инициализировать свою собственность.
    Не используйте _var вне сеттеров и геттеров. Вместо этого используйте self.var.
    вы можете изменить имя по умолчанию для вашего сеттера и getter

@property (nonatomic, strong, setter=setVariable:, getter=getVariable) NSObject *var;


    У rmaddy есть идеальный ответ... но у меня был сохранен как проект уже... Я буду быстрее отвечать в следующий раз...

ответил(а) 2021-01-25T21:15:17+03:00 5 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема