Objective-C: Пользовательские методы доступа BOOL (геттер и сеттер)

Я знаю, что кто-то уже спрашивал о написании геттера и сеттера для переменной BOOL. Но если я определяю пользовательские методы получения и установки setImmediate и isImmediate соответственно, я бы хотел, чтобы passcode.immediate = NO тоже работал.

У меня нет переменных экземпляра, но, может быть, я должен? Я мог бы добавить один для NSDate *lastUnlocked.

Вот соответствующий код:

// PasscodeLock.h

extern NSString *const kPasscodeLastUnlocked;

@interface PasscodeLock : NSObject {

}

- (BOOL)isImmediate;
- (void)setImmediate:(BOOL)on;

- (NSDate *)lastUnlocked;
- (void)resetLastUnlocked;
- (void)setLastUnlocked:(NSDate *)lastUnlocked;

@end


// PasscodeLock.m

#import "PasscodeLock.h"

NSString *const kPasscodeLastUnlocked    = @"kPasscodeLastUnlocked";

@implementation PasscodeLock

#pragma mark PasscodeLock

- (BOOL)isImmediate {
    return self.lastUnlocked == nil;
}

- (void)setImmediate:(BOOL)on {
    if (on) {
        [self resetLastUnlocked];
    } else {
        self.lastUnlocked = nil;        
    }
}

- (NSDate *)lastUnlocked {
    return [[NSUserDefaults standardUserDefaults] objectForKey:kPasscodeLastUnlocked];
}

- (void)resetLastUnlocked {
    NSDate *now = [[NSDate alloc] init];
    self.lastUnlocked = now;
    [now release];
}

- (void)setLastUnlocked:(NSDate *)lastUnlocked {
    [[NSUserDefaults standardUserDefaults] setObject:lastUnlocked forKey:kPasscodeLastUnlocked];
}

Затем в контроллере представления, который имеет PasswordLock *passwordLock в качестве переменной экземпляра, я хочу сделать passcode.immediate = NO, но получаю сообщение об ошибке «Свойство 'immediate' не найдено в объекте типа 'PasscodeLock *'».

Как заставить passcode.immediate = NO работать?


person ma11hew28    schedule 03.05.2011    source источник
comment
Почему ваш -lastUnlocked возвращает NSString, а -setLastUnlocked: принимает NSDate?   -  person kennytm    schedule 03.05.2011


Ответы (3)


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

foo.immediate

в вашем коде предполагается, что геттер и сеттер имеют имена -immediate и -setImmediate: соответственно. Ваш геттер назван неправильно. Лучший способ обойти это — объявить свойство, как уже сказали Марк и Кенни, но вы можете также изменить имя своего геттера.

Дело в том, что вам не нужны объявленные свойства для использования точечного синтаксиса, но если вы собираетесь использовать точечный синтаксис, то объявленные свойства являются рекомендуемым способом объявления геттера и сеттера.

person JeremyP    schedule 03.05.2011
comment
Спасибо. Я просто изменил имя геттера с -isImmediate на -immediate. - person ma11hew28; 07.05.2011

Вам нужно что-то вроде

@property (nonatomic, getter=isImmediate) BOOL immediate;

в вашем файле .h и, конечно же, оператор @synthesize в вашем файле .m. Это создает свойство И определяет имя вашего метода получения.

person Mark Granoff    schedule 03.05.2011
comment
Неатомарная часть является избыточной для свойства assign. - person JeremyP; 03.05.2011

Объявите такое свойство в @interface:

@interface PasscodeLock : NSObject {

}
@property(dynamic, getter=isImmediate,
                   setter=setImmediate:) BOOL immediate;
// etc.
@end

(Часть setter= не является обязательной)

person kennytm    schedule 03.05.2011