如何覆盖具有自己属性的属性对象的setter方法?

时间:2016-01-18 17:56:13

标签: objective-c setter

我有一个抽象类AuthResult,它具有属性 - Token模型类。

#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类中的setter方法以处理不同的情况。例如。在令牌刷新请求之后,它的refreshToken属性为空,所以我不需要删除它。

我尝试了这种方法 - AuthResult类中的setter:

- (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”对象。但我无法访问HIS属性。

请指教。谢谢

2 个答案:

答案 0 :(得分:1)

  

但它不起作用。它使AuthResult类中的标记对象始终为空。

您的媒体资源token引用类型,默认值为nil

在您提供的代码中,您永远不会将任何值分配给token 本身。例如声明:

_token.accessToken = token.accessToken;

是一个指令,用于为accessToken中的值引用的引用的对象的_token分配一个值,但由于_token中的值永远不会您从nil更改了没有引用的对象来更改其属性。由于Objective-C的规则,你不会在这里得到一个错误,某些语言会给出错误,这个动作什么都不做。

问题是你真正想做什么?

如果,我在这里猜测你的意图,你的AuthResult对象应该有自己的Token对象,其属性应该由你的setter修改然后你几乎就在那里,你只需要为你的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;
   ...

虽然这解决了您的直接问题,但它不能解决大型设计问题,您是否应该这样做? getter可以读取_token中的值,因为它是一个引用,这意味着某人可以使用getter更改其属性,然后进行设置。如果_token引用的对象意图属于您可能不是您想要的AuthResult实例,例如,您可能希望getter返回副本

所以想想你的模特。

HTH

答案 1 :(得分: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;
}
}