【发布时间】:2013-12-16 15:00:53
【问题描述】:
关于类别属性问题有很多问题。 我知道解决这个问题的一些可能性:
从我的角度来看,两者都不干净,因为当创建此类属性的对象被释放时,分配的内存永远不会被清除。
类别是保持代码整洁和为现有类动态添加功能的好方法。它们有助于将功能分组并在更多开发人员之间分配实施工作。
类别的坏处是缺少存储。
我现在多次遇到这个问题,我想知道以下是否会以一种干净的方式解决这个问题,同时也注意内存,以及是否有任何我现在看不到的问题。
有一个限制,我可以忽略,因为我是一名框架开发人员:我能够创建自己的自己的根类,而其他所有的类可以继承。
首先声明新的根对象:
@interface RootObject : NSObject
- (void)setRuntimeProperty:(id)runtimeProperty forKey:(id<NSCopying>)key;
- (id)runtimePropertyForKey:(id)key;
@end
配合相应的实现:
#import "RootObject.h"
@interface RootObject ()
@property (readwrite) NSMutableDictionary *runtimeProperties;
@end
@implementation RootObject
@synthesize runtimeProperties = _runtimeProperties;
- (id)init {
self = [super init];
if (self)
{
_runtimeProperties = [[NSMutableDictionary alloc] initWithCapacity:1];
}
return self;
}
- (void)dealloc {
[_runtimeProperties release];
_runtimeProperties = nil;
[super dealloc];
}
- (id)runtimePropertyForKey:(id)key {
return [self.runtimeProperties objectForKey:key];
}
- (void)setRuntimeProperty:(id)runtimeProperty forKey:(id<NSCopying>)key {
if (key)
{
if (runtimeProperty)
{
[self.runtimeProperties setObject:runtimeProperty forKey:key];
}
else
{
[self.runtimeProperties removeObjectForKey:key];
}
}
}
@end
通过使用RootObject 而不是NSObject,应该很容易将“属性”添加到类的类别中。考虑上课MyClass
@interface MyClass : RootObject
// some interface here
@end
在此类之上实现特殊行为时,您现在可以添加如下属性:
@interface MyClass (specialBehavior)
@property (nonatomic, retain) NSString *name;
@property (nonatomic, copy) NSDate *birthday;
@end
有相应的实现:
@implementation MyClass (specialBehavior)
@dynamic name;
- (NSString *)name {
return [self runtimePropertyForKey:@"name"];
}
- (void)setName:(NSString *)name {
[self setRuntimeProperty:name forKey:@"name"];
}
@dynamic birthday;
- (NSDate *)birthday {
return [self runtimePropertyForKey:@"birthday"];
}
- (void)setBirthday:(NSDate *)birthday {
[self setRuntimeProperty:[birthday copy] forKey:@"birthday"];
}
@end
只需在 setter 方法中添加必要的调用,这样的实现也可以兼容 KVO。 非常直截了当,但我想知道我是否错过了一些重要的事情? (例如,具有许多此类声明的属性或使用许多此类对象的运行时性能非常非常差)
【问题讨论】:
-
如果您正在开发有问题的类并且只是使用类别进行组织,为什么不直接将必要的属性添加到您的类中呢?仅当您无法更改类定义时,类别的存储“问题”才适用。
-
@Caleb:事情并不像这里显示的那么简单。通过直接更改
MyClass,它会随着每个特殊行为的实现而增长和增长。并回到框架开发;行为将与MyClass绑定,即使此类行为仅用于特殊项目。所以我的目标是拥有只有根功能的苗条类。 -
随着每一种特殊行为而成长和成长 嗯,是的,当您向类添加属性时会发生这种情况。 即使这样的行为只在一个特殊的项目中使用 那么为什么要将这些行为添加到类本身呢?子类化似乎是解决这两个问题的合理解决方案。如果您的解决方案适合您,那就太好了(但请先阅读 Jesse 的回答)。
标签: ios objective-c properties objective-c-category