Jas*_*ary 6 lazy-loading ios ios5
我正在迁移一些遗留代码(iOS 5之前的版本),我懒得加载一些readonly属性.我想用ARC将此代码更新到iOS 5+.但我刚刚学习ARC.
.H
@property (nonatomic, retain, readonly) NSDateFormatter *timeFormatter;
Run Code Online (Sandbox Code Playgroud)
.M
- (NSDateFormatter *)timeFormatter {
if (timeFormatter == nil) {
timeFormatter = [[NSDateFormatter alloc] init];
[timeFormatter setDateFormat:@"h:mm a"];
}
return timeFormatter;
}
Run Code Online (Sandbox Code Playgroud)
我试图简单地更新我的代码,但收到:分配给readonly属性.
.H
@property (nonatomic, strong, readonly) NSDateFormatter *timeFormatter;
Run Code Online (Sandbox Code Playgroud)
.M
- (NSDateFormatter *)timeFormatter {
if (self.timeFormatter == nil) {
self.timeFormatter = [[NSDateFormatter alloc] init];
[self.timeFormatter setDateFormat:@"h:mm a"];
}
return self.timeFormatter;
}
Run Code Online (Sandbox Code Playgroud)
我还审查了:
readonly使用ARC在iOS 5+中延迟加载属性的正确方法是什么?非常感谢.h和.m的代码示例.
Mar*_*n R 14
对于自定义(惰性)getter方法,您必须直接访问实例变量(无论您是否使用ARC).所以你应该将属性合成为
@synthesize timeFormatter = _timeFormatter;
Run Code Online (Sandbox Code Playgroud)
然后你的getter方法是
- (NSDateFormatter *)timeFormatter {
if (_timeFormatter == nil) {
_timeFormatter = [[NSDateFormatter alloc] init];
[_timeFormatter setDateFormat:@"h:mm a"];
}
return _timeFormatter;
}
Run Code Online (Sandbox Code Playgroud)
如果同时从多个线程访问属性,则只需添加一些同步机制,也可以独立于ARC.
(注:较新版本的Xcode可以创建一个@synthesize自动的语句,并使用下划线前缀实例变量在这种情况下,但是由于属性是只读的,你提供一个getter方法时,Xcode不会.不会自动合成属性.)
ADDED:以下是一个完整的代码示例,以方便您:
MyClass.h:
#import <Foundation/Foundation.h>
@interface MyClass : NSObject
@property (nonatomic, strong, readonly) NSDateFormatter *timeFormatter;
@end
Run Code Online (Sandbox Code Playgroud)
MyClass.m:
#import "MyClass.h"
@implementation MyClass
@synthesize timeFormatter = _timeFormatter;
- (NSDateFormatter *)timeFormatter {
if (_timeFormatter == nil) {
_timeFormatter = [[NSDateFormatter alloc] init];
[_timeFormatter setDateFormat:@"h:mm a"];
}
return _timeFormatter;
}
@end
Run Code Online (Sandbox Code Playgroud)
更多信息:事实上timeFormatter,如果属性合成为,则ARC 之前的getter方法也可以在不更改ARC的情况下工作
@synthesize timeFormatter; // or: @synthesize timeFormatter = timeFormatter;
Run Code Online (Sandbox Code Playgroud)
唯一的"错误"你做了更换timeFormatter由self.timeFormattergetter方法里面.这会产生两个问题:
self.timeFormattergetter方法会导致无限递归.self.timeFormatter由于只读属性,因此不允许进行设置.因此,如果您只是保留timeFormattergetter方法(使用方法中的timeFormatter实例变量),那么它也适用于ARC.
我仍然建议在我的代码示例中为带有下划线的属性添加实例变量,因为Xcode对自动合成属性的处理方式相同.
(我希望这有助于而且不会增加混乱!)
Readonly属性就是:只读.不应该涉及制定者.好的部分是,如果您在类扩展中重新声明变量(通常使用一对空括号),作为readwrite(或者甚至只是完全删除readonly),那么您可以在.m中分配它,但是类可以导入它会将其视为只读.
@interface MyClass ()
@property (nonatomic, strong) NSDateFormatter *timeFormatter;
@end
Run Code Online (Sandbox Code Playgroud)
这种重新声明允许更清晰的方式在内部访问和改变属性,而不需要使用脆弱的iVar综合(现在编译器为您完成了这个现象).你可以,或者当然,仍然使用iVar,如另一个答案所示,但不需要在-init或合成的getter之外进行iVar访问.*
*正如Martin正确指出的那样,即使你的任务成功,你仍然会导致无限递归,所以iVar访问是必要的,除非你明确声明一个getter,然后你可以使用属性访问.
| 归档时间: |
|
| 查看次数: |
2233 次 |
| 最近记录: |