首页 > 解决方案 > 使一个属性强,非原子的objective-c

问题描述

我有一个多视图应用程序并使用一个对象来跟踪我的登录用户。我的 User.h 看起来像这样

@interface User : NSObject

@property (strong, nonatomic) NSDictionary *data;

@property (weak, nonatomic) NSString *uid;
@property (weak, nonatomic) NSString *firstName;
@property (weak, nonatomic) NSString *lastName;
@property (weak, nonatomic) NSString *dob;
@property (weak, nonatomic) NSString *gender;
@property (weak, nonatomic) NSString *avatarURL;
@property (assign, nonatomic) NSInteger status;

- (void)setPropertiesWith:(NSDictionary *)data;

User.m 看起来像这样

#import "User.h"

@implementation User
/*
 * set properties
 */
- (void)setPropertiesWith:(NSDictionary *)data{
    self.data = data;

    self.uid = self.data[@"uid"];
    self.firstName = self.data[@"firstName"];
    self.lastName = self.data[@"lastName"];
    self.dob = self.data[@"dob"];
    self.gender = self.data[@"gender"];
    self.status = [[self.data valueForKeyPath:@"status"] intValue];
    self.avatarURL = self.data[@"avatarURL"];
}

@end

我的数据很弱,但在其中一种观点中它会变成空 - 我相信 ARC 正在发布它。如果我错了,请纠正我。

我有两个问题:

  1. 使用此设置,数据为strong,其余属性为weak,这是否有任何潜在风险?

  2. 我应该将数据设为 ivar 并保持其余部分不变吗?

这些属性的存在没有实际原因(除了我糟糕的课程设计技巧)。我只是觉得这很有趣,并想了解发生了什么。

标签: iosobjective-cautomatic-ref-counting

解决方案


您问:

  1. 使用此设置,数据为strong,其余属性为weak,这是否有任何潜在风险?

是的,如果您是 ,那么您nildictionary所有属性都可能变为nil,假设您在其他地方没有其他对它们的强引用。

  1. 我应该将数据设为 ivar 并保持其余部分不变吗?

我什至不会把它变成一个 ivar(除非有一些其他的要求来保存你没有与我们分享的这个)。它应该只是一个局部变量,并创建您的属性copy(或strong)。


我建议(a)摆脱NSDictionary财产和(b)使NSString财产成为copy(或strong),而不是weaksetPropertiesWith另外,我只是定义一个初始化程序,而不是一个方法:

// User.h

@interface User : NSObject

@property (copy, nonatomic) NSString *uid;
@property (copy, nonatomic) NSString *firstName;
@property (copy, nonatomic) NSString *lastName;
@property (copy, nonatomic) NSString *dob;
@property (copy, nonatomic) NSString *gender;
@property (copy, nonatomic) NSString *avatarURL;
@property (assign, nonatomic) NSInteger status;

- (instancetype)initWithDictionary:(NSDictionary *)dictionary;

@end

// User.m

@implementation User

- (instancetype)initWithDictionary:(NSDictionary *)dictionary {
    if ((self = [super init])) {
        self.uid       = dictionary[@"uid"];
        self.firstName = dictionary[@"firstName"];
        self.lastName  = dictionary[@"lastName"];
        self.dob       = dictionary[@"dob"];
        self.gender    = dictionary[@"gender"];
        self.status    = [dictionary[@"status"] intValue];
        self.avatarURL = dictionary[@"avatarURL"];
    }

    return self;
}

@end

然后,调用者会这样做:

User *user = [[User alloc] initWithDictionary:someDictionary];

您可以在此处考虑其他改进(例如readonly,公共接口、声明可空性、字典上的轻量级泛型等),但以上可能是一个很好的起点。


顺便说一句,如果您想知道我为什么要制作这些copy而不是strong,我们只是想保护自己,以防调用者传递了 a NSMutableString(这是一个NSString子类)并在以后意外地对其进行了变异。这只是更安全一点,更具防御性的模式。


推荐阅读