我正在创建一个具有isDirty
标志的基类。它在其属性之一的任何时候都会更改,但由于它是基类,因此它不知道它的属性是什么。所以基本上,在每个子类上,我必须覆盖每个- set:
方法,如下所示:
- (id) setName:(NSString *)value {
if ([name isEqualToString:value]) {
return;
}
[name autorelease];
name = [value retain];
isDirty = YES; //Here's the important bit
}
几乎每一行都是自动合成的setter所能做的。有什么方法可以覆盖@synthesize
实际创建的内容吗?
我已经提出了其他选项,但它们看起来在运行时比这种方法慢得多。我已经考虑过添加一个对象来观察它自己的属性更改,或创建一个通用函数来完成所有这些并将地址传递给iVar和新值,但仍然需要覆盖setter。
有什么想法吗?如果它有所作为,它适用于iPhone应用程序。
答案 0 :(得分:8)
这里有几个问题:
(1)如果您担心setter性能,则不应在setter中使用-isEqualToString :.做一个指针比较,因为在这种情况下这一切都很重要。
(2)如果你有一个NSString属性,你应该复制set。复制对于不可变字符串是免费的,并且会将你的培根保存为可变字符串(通过防止调用者从你下面改变字符串)。
(3)再次表现;你检查了相等,但然后使用autorelease。这会产生不必要的开销。
(4)*它们似乎在运行时会慢得多*表示您实际上没有尝试过,没有发现性能问题,并且过早地优化了代码。给定(1)和(3),可能更容易解决性能问题。
我的建议:
(1)使用@synthesize。它将生成正确和快速的代码,解决(1)和(3)。
(2)使用KVO或其他机制之一。在通过仪器和量化确定性能问题之前,您没有性能问题。
(3)考虑使用CoreData(当然,除非你的目标是OS 2.x)。示例代码来自显然是模型对象的东西。如果您的代码很好地考虑到模型/视图/控制器中,那么在模型层使用CoreData可以简化您的应用程序,而CoreData可以很好地完成变更跟踪。
答案 1 :(得分:7)
我无法知道这会让你覆盖@synthesize所做的事情。
在一天结束时,它用于创建基本的访问方法 - 即。那些没有特定行为的人。
也许你应该研究关键价值编码和关键价值观察?
答案 2 :(得分:3)
答案 3 :(得分:1)
如果您编写自己的访问方法,@synthesize会尊重它。 @synthesize优先考虑您自己编写的访问器。只需提供您喜欢的访问者,就可以忽略@synthesize。例如,您可以实现一个只在不存在属性时才创建属性的访问器。
示例:
@synthesize standardUserDefaults;
- (NSUserDefaults *)standardUserDefaults {
NSLog(@"standardUserDefaults");
if (!standardUserDefaults) {
NSLog(@"standardUserDefaults new");
self.standardUserDefaults = [NSUserDefaults standardUserDefaults];
}
return standardUserDefaults;
}
这里“合成器”是合成的,而“吸气器”不合成。