为 objective-c 制造一个 属性 强的非原子
making one property strong,nonatomic for 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 正在发布它。如果我错了,请纠正我。
我有两个问题:
使用此设置,数据为 strong
,其余属性为 weak
,这是否存在潜在风险?
我应该把数据做成ivar,其余的保持原样吗?
这些属性的存在没有实际原因(除了我糟糕的 class 设计技巧)。我只是觉得它很有趣,想了解这是怎么回事。
你问过:
- With this setup, the data being
strong
and the rest of the properties being weak
, is there any potential risk to this?
是的,如果您 nil
dictionary
,您的所有属性都可能会变成 nil
,假设您在别处没有对它们的其他强引用。
- Should I make the data an ivar and keep the rest as is?
我什至不会将其设为 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
public 接口、声明可空性、字典上的轻量级泛型等),但以上内容可能是一个很好的起点。
顺便说一句,如果你想知道为什么我使用这些 copy
而不是 strong
,我们只是想保护自己,以防调用者传递 NSMutableString
(这是一个NSString
子类),后来不小心变异了。这只是更安全一点,更具防御性的模式。
我有一个多视图应用程序并使用一个对象来跟踪我的登录用户。我的 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 正在发布它。如果我错了,请纠正我。
我有两个问题:
使用此设置,数据为
strong
,其余属性为weak
,这是否存在潜在风险?我应该把数据做成ivar,其余的保持原样吗?
这些属性的存在没有实际原因(除了我糟糕的 class 设计技巧)。我只是觉得它很有趣,想了解这是怎么回事。
你问过:
- With this setup, the data being
strong
and the rest of the properties beingweak
, is there any potential risk to this?
是的,如果您 nil
dictionary
,您的所有属性都可能会变成 nil
,假设您在别处没有对它们的其他强引用。
- Should I make the data an ivar and keep the rest as is?
我什至不会将其设为 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
public 接口、声明可空性、字典上的轻量级泛型等),但以上内容可能是一个很好的起点。
顺便说一句,如果你想知道为什么我使用这些 copy
而不是 strong
,我们只是想保护自己,以防调用者传递 NSMutableString
(这是一个NSString
子类),后来不小心变异了。这只是更安全一点,更具防御性的模式。