【问题标题】:making one property strong,nonatomic for objective-c使一个属性强,非原子的objective-c
【发布时间】:2019-02-27 00:06:23
【问题描述】:

我有一个多视图应用程序并使用一个对象来跟踪我的登录用户。我的 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 并保持其余部分不变吗?

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

【问题讨论】:

  • 为什么要弱化属性?
  • @rmaddy 新手错误。

标签: ios objective-c automatic-ref-counting


【解决方案1】:

你问:

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

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

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

我什至不会将其设为 ivar(除非您有其他未与我们分享的保存要求)。它应该只是一个局部变量,并使您的属性为copy(或strong)。


我建议 (a) 摆脱 NSDictionary 属性和 (b) 将 NSString 属性设置为 copy(或 strong),而不是 weak。另外,我只定义一个初始化器,而不是 setPropertiesWith 方法:

// 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,我们只是想保护自己,以防调用者传递了 NSMutableString(这是一个 NSString 子类)并意外突变稍后。这只是更安全一点,更具防御性的模式。

【讨论】:

    猜你喜欢
    • 2012-04-09
    • 2012-12-25
    • 1970-01-01
    • 1970-01-01
    • 2012-06-10
    • 2013-07-08
    • 2014-02-01
    • 2011-12-16
    • 2013-05-17
    相关资源
    最近更新 更多