Objective c 这是什么意思&引用;可写原子属性';文件管理器&x27;无法将合成的setter/getter与用户定义的setter/getter配对;
可能重复:Objective c 这是什么意思&引用;可写原子属性';文件管理器&x27;无法将合成的setter/getter与用户定义的setter/getter配对;,objective-c,ios,xcode,xcode4,Objective C,Ios,Xcode,Xcode4,可能重复: 我有一个头文件,其中声明了一个原子属性,如下所示: @property (retain) FileManager *fileManager; 然后,我在实现文件中综合: @synthesize fileManager; 然后我为惰性初始化编写自己的访问器: - (FileManager*)fileManager { if (fileManager) { return fileManager; } FileManager *fm = [[
我有一个头文件,其中声明了一个原子属性,如下所示:
@property (retain) FileManager *fileManager;
然后,我在实现文件中综合:
@synthesize fileManager;
然后我为惰性初始化编写自己的访问器:
- (FileManager*)fileManager {
if (fileManager) {
return fileManager;
}
FileManager *fm = [[FileManager alloc] init];
self.fileManager = fm;
[fm release];
return fileManager;
}
一切都很完美,Xcode 3.2从未抱怨过。但Xcode 4警告:
可写原子属性“fileManager”无法对合成的
具有用户定义的setter/getter的setter/getter
当我做到这一点时,它试图说:“你不能像过去3年那样覆盖综合的能手/二传手,即使它工作得很好!”
显然,令人惊讶的警告是愚蠢的。这个属性真的需要线程安全,我真的想要这个延迟初始化。我现在该怎么办
编辑:根据,此处缺少@synchronize
代码如何手动使此访问器正确线程安全?
我试着把它改写成这样:
- (FileManager*)fileManager {
@synchronized(self) {
if (fileManager) {
return fileManager;
}
FileManager *fm = [[FileManager alloc] init];
self.fileManager = fm;
[fm release];
return fileManager;
}
}
但警告并没有消失。因此,当我正确地回答了另一个问题时,消除这个警告的唯一方法就是要么不自定义合成原子属性访问器,要么完全省略@synthesis,然后手工完成:访问器和变异器。当然,这会很糟糕。有更好的办法解决这个问题吗
如果我将其设置为@dynamic fileManager
而不是@synthetic fileManager
,这意味着什么
编辑:因此我尝试使用
@dynamic
而不是@synthesis
。它实际上意味着手动实现访问器和mutator。那我为什么还要将它声明为@dynamic
?您可以使用过去几年中许多苹果代码示例中所示的惰性初始化模式。根据惯例,通常会有一个对应的局部变量,该变量带有一个前导下划线(\uu
)。在@synthesis语句中,将其分配给ivar:
@synthesize fileManager = _fileManager;
您可以懒散地创建局部变量
-(FileManager) fileManager {
if (_fileManager != nil) return _fileManager;
// etc...
}
如果声明的@property是原子属性(默认值),则必须使用@dynamic,让编译器@合成所有内容,或者提供setter和getter的实现。Nice,但这如何解决我上面描述的问题呢?我已经在使用延迟初始化,在这个例子中它甚至不是线程安全的,不是吗?或者这是我不懂的高级哈佛巫术?;-)你还在收到警告?是的,看起来你是对的。但老实说:我希望你不是:-)他是。是新的LLVM编译器不喜欢这样。‘哈佛伏都教’说原子性!=线程安全