Joh*_*und 2 objective-c uiviewcontroller categories subclassing
正如标题所描述的那样,我希望为每个UIViewController和每个子类(如UITableViewController)添加自定义属性.我的第一个想法是创建一个类别,但后来我意识到不能在其中添加ivars,所以我无法合成属性.如果我只是子类UIViewController并在那里添加东西,它不会影响其他子类.
基本上我的目的是为我的'UINavigationController'子类添加一个自定义工具栏(不,我不能出于各种原因使用默认值).它需要询问每个viewController是否需要工具栏,以及 - 在这种情况下 - 是否为toolbarItems数组.这有点像我相信UIToolbar的工作原理吗?
你会怎么做?
ipm*_*mcc 14
使用Objective-C的关联对象API可以添加属性(使用后备存储).我甚至为此目的写了一个小宏.但在宏之前,这就是"展开"的样子:
#import <objc/runtime.h>
@interface UIViewController (SOAdditions)
@property (atomic, readwrite, copy) NSString* myProperty;
@end
static void * const kMyPropertyAssociatedStorageKey = (void*)&kMyPropertyAssociatedStorageKey;
@implementation UIViewController (SOAdditions)
- (void)setMyProperty:(NSString *)myProperty
{
objc_setAssociatedObject(self, kMyPropertyAssociatedStorageKey, myProperty, OBJC_ASSOCIATION_COPY);
}
- (NSString*)myProperty
{
return objc_getAssociatedObject(self, kMyPropertyAssociatedStorageKey);
}
@end
Run Code Online (Sandbox Code Playgroud)
您可以在此处找到相关存储的文档.您应该知道使用关联对象会有性能(速度和内存)损失.他们是一个巧妙的伎俩,但你可能想问自己是否有更好的方法来做你想做的事情.(招最巧妙的部分,如果你问我,是运行时将处理-releases上-dealloc你,根据您指定的政策;请参阅该文档获取更多信息)
现在这是宏:
#ifndef ASSOCIATED_STORAGE_PROPERTY_IMP
#define THREE_WAY_PASTER_INNER(a, b, c) a ## b ## c
#define THREE_WAY_PASTER(x,y,z) THREE_WAY_PASTER_INNER(x,y,z)
#define ASSOCIATED_STORAGE_PROPERTY_IMP(type, setter, getter, policy) \
static void * const THREE_WAY_PASTER(__ASSOCIATED_STORAGE_KEY_, getter, __LINE__) = (void*)&THREE_WAY_PASTER(__ASSOCIATED_STORAGE_KEY_, getter,__LINE__); \
\
- (type)getter { return objc_getAssociatedObject(self, THREE_WAY_PASTER(__ASSOCIATED_STORAGE_KEY_, getter,__LINE__) ); } \
\
- (void)setter: (type)value { objc_setAssociatedObject(self, THREE_WAY_PASTER(__ASSOCIATED_STORAGE_KEY_, getter,__LINE__) , value, policy); } \
#endif
Run Code Online (Sandbox Code Playgroud)
如果你在头文件中弹出它,那么上面的例子可以简化为:
#import <objc/runtime.h>
@interface UIViewController (SOAdditions)
@property (atomic, readwrite, copy) NSString* myProperty;
@end
@implementation UIViewController (SOAdditions)
ASSOCIATED_STORAGE_PROPERTY_IMP(NSString*, setMyProperty, myProperty, OBJC_ASSOCIATION_COPY)
@end
Run Code Online (Sandbox Code Playgroud)
不言而喻,您在@property声明中声明的策略(即保留/复制/分配,原子/非原子)需要与您在使用宏时使用的策略匹配(和/或调用底层API,如果您'不使用宏)否则,你最终会泄漏内存(或崩溃).
另外,我再说一遍强调.这个技巧不是"免费的"所以请务必测量性能并确保使用它获得的任何好处都是值得的.
编辑:我将对我关于相关对象存储的性能损失的强烈和可怕的警告进行回溯.有一个惩罚,但快速调查告诉我,以这种方式实施的属性并没有比他们的@synthesized和ivar支持的等价物更糟糕.该测试有点人为,但有10,000,000个对象,每个对象有5个关联存储支持的iVars,我看到性能设置和获取速度降低约30%.这真的不是那么可怕,恕我直言.我期待更糟糕.执行与set操作相关联的内存管理(保留,复制)所花费的时间使得关联查找的开销相形见绌.
| 归档时间: |
|
| 查看次数: |
3008 次 |
| 最近记录: |