Свойства Obj-C, области действия и вспомогательные классы - PullRequest
0 голосов
/ 09 декабря 2011

Я пытался понять некоторые нюансы системы iOS и один пункт, который мне не понятен. Я создавал класс для инкапсуляции методов для доступа к календарю, который включал в себя создание событий, одноэлементное хранилище событий и асинхронную операцию выборки.

Была смесь переменных класса и переменных экземпляра, но мне было трудно заставить это работать.

Мой вопрос такой.

Давайте посмотрим на этот проект.

http://developer.apple.com/library/ios/#samplecode/SimpleDrillDown

Класс Play инкапсулирует информацию об игре.

@interface Play : NSObject
@property (nonatomic, strong) NSString *title;
@property (nonatomic, strong) NSArray *characters;
@property (nonatomic, strong) NSString *genre;
@property (nonatomic, strong) NSDate *date; 
@end

#import "Play.h"
@implementation Play
@synthesize title, characters, genre, date;
@end

Из-за синтеза, если я правильно понимаю, нет метода dealloc.

Теперь другие методы не определены.

В контроллере деталей примера проекта объект вообще не инициализирован, но свойства доступны по ссылке, что меня смутило. Если я пытаюсь написать методы в Play, методы не могут изменить значения в свойствах. Например, если вы попытались объединить класс Data Controller с классом Play , я заметил, что методы не могут устанавливать и получать значения из свойств.

Например, если я добавлю в класс Play:

(void)createSamplePlay
{
    self.title = @"Play 1";
    self.characters = [NSArray arrayWithObject:[NSString stringWithFormat:@"Character 1"]];
    self.genre = @"Genre 1";
    self.date = [NSDate date];
}

Затем я вызываю метод внутри Details Controller, на самом деле ничего не меняется. Если я переместу метод в Подробности контроллера, объявлю статическое типизированное свойство Play *play, затем вызову метод [self createSamplePlay]; и изменится с self на play, тогда, конечно, методы будут работать.

Я не знал, было ли в моем понимании фундаментальное недоразумение, или это просто код выше, это написать, и я получил ошибку в моем реальном и гораздо более длинном проекте.

Тем временем я буду продолжать читать PDF-файлы Obj-C с developer.apple.com .

редактирование:

Извините, это был плохой пример моего последнего намерения.

Допустим, я хотел написать метод, который делает это:

-(void)fillInMissingGenre
{
    if([self.title caseInsensitiveCompare:@"Romeo and Juliet"] == 0){
        self.genre = @"Tragedy";
    }
}

В примере кода Play создается с помощью Data Controller , который возвращается на контроллер Root , а затем передается на Detail Controller , через свойство Play Detail Controller. И Корень, и Деталь должны иметь возможность вызывать методы Play , если только один из предыдущих объектов не решил разыменовать объект.

Я начинаю подозревать, что это является причиной моих проблем, поскольку иногда объект Play возвращает nil для всего, а затем иногда я получаю Exec_Bad_Access. Если бы я только научился использовать этот отладчик. , .

Ответы [ 2 ]

3 голосов
/ 09 декабря 2011

Из-за синтеза, если я правильно понимаю, нет метода dealloc.

Это неправильно.Нет dealloc, потому что этот код написан для ARC (Автоматический подсчет ссылок).Это не имеет ничего общего с @synthesize.

Кроме этого, я думаю, что вам не хватает разницы между классом и объектом.Свойства определены в Play классе , но для их фактического использования (для хранения данных) необходимо создать объект или экземпляр объекта.учебный класс.Вы можете сделать это с помощью:

Play *myPlay = [[Play alloc] init];

Теперь вы можете использовать объект myPlay (или, точнее, myPlay - указатель на объект) для выполнения таких вещей, как `myPlay.title = @ "Play 1";

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

Play *myPlayNoInstance;
myPlayNoInstance.title = @"Play 2"; // doesn't do anything

Поскольку здесь myPlayNoInstance - указатель, который выполняетне указывает на выделенный объект.

1 голос
/ 09 декабря 2011

Если я правильно понимаю ваши намерения, createSamplePlay - это заводской метод.Если это предположение верно, вы должны объявить его в классе Play (обратите внимание на + - это индикатор метода класса) и переписать реализацию следующим образом:

+ (id) createSamplePlay
{
    self = [[Play  alloc] init];
    self.title = @"Play 1";
    self.characters = [NSArray arrayWithObject:[NSString stringWithFormat:@"Character 1"]];
    self.genre = @"Genre 1";
    self.date = [NSDate date];
    return self;
}

Позже выможете использовать его в своем коде:

Play *sample = [Play createSamplePlay];

Из-за синтеза не существует метода dealloc, если я правильно понимаю.

Нет, dealloc неиз-за автоматического подсчета ссылок (наличие модификатора strong говорит о том, что вы находитесь на земле ARC).

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