2016-01-18 3 views
0

У меня есть абстрактный класс AuthResult, который имеет имущество - Token модель класса.Как переопределить метод setter для объекта property, который имеет собственные свойства внутри?

#import <Foundation/Foundation.h> 

@class Token; 

@interface AuthResult : NSObject 

+ (instancetype)sharedInstance; // designated initializer 

@property (readwrite, strong, nonatomic) Token *token; 
@property (readwrite, nonatomic) BOOL isAuthorized; 

@end 

Token модель класса, в свою очередь, имеет 5 свойств в пределах:

#import <Foundation/Foundation.h> 

@interface Token : NSObject 

@property (readwrite, strong, nonatomic) NSString *accessToken; 
@property (readwrite, strong, nonatomic) NSDate *expirationDate; 
@property (readwrite, strong, nonatomic) NSString *tokenType; 
@property (readwrite, strong, nonatomic) NSString *scope; 
@property (readwrite, strong, nonatomic) NSString *refreshToken; 

@end 

Моя цель состоит в том, чтобы переопределить метод сеттер в AuthResult классе для того, чтобы обрабатывать различные случаи. Например. после запроса обновления токена у него есть refreshToken свойство пустое, поэтому мне не нужно его удалять.

Я попробовал этот подход - сеттер в AuthResult классе:

- (void)setToken:(Token *)token { 
    _token.accessToken = token.accessToken; 
    _token.expirationDate = token.expirationDate; 
    _token.tokenType = token.tokenType; 
    _token.scope = token.scope; 

    if (token.refreshToken != nil) { 
     // DO NOT OVERRIDE REFRESH_TOKEN HERE (after refresh token request it comes as null) 
     _token.refreshToken = token.refreshToken; 
    } 
} 

Но это не работает. Он делает объект токена в классе AuthResult всегда пустым.

Как я вижу - у меня нет доступа к свойствам объекта. У меня есть доступ к переменной экземпляра - «_token». Но у меня нет доступа к его свойствам.

Прошу совета. Спасибо

+0

я думаю, вы должны проверить '_token == nil' перед присвоением значения и создать его, если это необходимо? – Lucho

ответ

1

Но это не работает. Это делает объект токена в классе AuthResult всегда пустым.

Ваше имущество token имеет ссылочный тип и значение по умолчанию для таких является nil.

В коде, который вы поставили, никогда не присваивается значение tokenсам. Например, утверждение:

_token.accessToken = token.accessToken; 

не является инструкцией, чтобы присвоить значение в accessToken объекта ссылается значение в _token - но значение в _token никогда не изменяется вами из nil нет объект, на который ссылается изменение свойства. Из-за правил Objective-C здесь вы не получаете ошибку, которую некоторые языки дали бы, действие просто ничего не делает.

Вопрос в том, что вы действительно пытаетесь сделать?

Если, и я предполагаю, что в своем намерении здесь, ваш AuthResult объект должен иметь свой собственный Token объект, свойства которого должны быть изменены вашим сеттер, то вы почти там, вам просто нужно выделить Token объект для вашего AuthResult. Вы можете сделать это с помощью следующего кода:

- (void)setToken:(Token *)token 
{ 
    if(_token == nil) 
     _token = Token.new; // don't have a token yet, allocate one 
    // now update the fields of our _token from token 
    _token.accessToken = token.accessToken; 
    _token.expirationDate = token.expirationDate; 
    ... 

Хотя это решает вашу непосредственную проблему это не решает большую проблему проектирования, вы должны делать это?Значение в _token может быть прочитано получателем, и поскольку это ссылка, это означает, что его свойства могут быть изменены кем-то, использующим геттер, а затем устанавливая их. Если ссылка объекта на _token предназначена для вашего экземпляра AuthResult, возможно, это не то, что вы хотите, например, вы можете захотеть, чтобы геттер вернул копию .

Так что подумайте о своей модели.

НТН

+0

Большое спасибо за ответ. Я попробую завтра на работе –

+0

, если я правильно понял, я должен использовать эту структуру для возврата копии моего токен-объекта в getter? - 'return [_token copy];' –

+0

@BogdanLaukhin - Да, * если * вы хотите вернуть копию, как вы можете это сделать (при условии, что «Token» реализует «NSCopying», конечно). – CRD

0

Вы забыли инициализировать объект токена. Вы можете сделать это следующим образом:

- (void)setToken:(Token *)token { 
_token = [Token new]; //initialize Token Object 
_token.accessToken = token.accessToken; 
_token.expirationDate = token.expirationDate; 
_token.tokenType = token.tokenType; 
_token.scope = token.scope; 

if (token.refreshToken != nil) { 
    // DO NOT OVERRIDE REFRESH_TOKEN HERE (after refresh token request it comes as null) 
    _token.refreshToken = token.refreshToken; 
} 
} 
Смежные вопросы