1、过多逻辑分支,不够清晰,公共变量不利于系统维护和项目拓展;
2、安全性收到威胁,过多地方共享变量,变量的写入和读取在多线程下是危险的;
3、业务逻辑交叉过多时,很难保证数据-逻辑的一致性;
void指针(const void *)
。我们还需要指定一个内存管理策略,以告诉Runtime如何管理这个对象的内存。OBJC_ASSOCIATION_ASSIGN /**< Specifies a weak reference to the associated object. */
OBJC_ASSOCIATION_RETAIN_NONATOMIC/**< Specifies a strong reference to the associated object. * The association is not made atomically. */
OBJC_ASSOCIATION_COPY_NONATOMIC /**< Specifies that the associated object is copied.* The association is not made atomically. */
OBJC_ASSOCIATION_RETAIN /**< Specifies a strong reference to the associated object. * The association is made atomically. */
OBJC_ASSOCIATION_COPY /**< Specifies that the associated object is copied.* The association is made atomically. */
static char anObjectKey;
objc_setAssociatedObject(self, &anObjectKey, anObject, OBJC_ASSOCIATION_RETAIN)
id anObject = objc_getAssociatedObject(self, &anObjectKey);
objc_removeAssociatedObjects(anObject);
或者使用objc_setAssociatedObject函数将key指定的关联对象设置为nil;
- (void)setTapActionWithBlock:(void (^)(void))block
{
UITapGestureRecognizer *tapGR = objc_getAssociatedObject(self, &kJLActionHandlerTapGestureKey);
if (!tapGR)
{
tapGR = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(JL_handleActionForTapGesture:)];
[self addGestureRecognizer: tapGR];
objc_setAssociatedObject(self, & kJLActionHandlerTapGestureKey, tapGR, OBJC_ASSOCIATION_RETAIN);
}
objc_setAssociatedObject(self, & kJLActionHandlerTapBlockKey, block, OBJC_ASSOCIATION_COPY);
}
- (void) JL_handleActionForTapGesture:(UITapGestureRecognizer *)sender
{
if (sender.state == UIGestureRecognizerStateRecognized)
{
void(^action)(void) = objc_getAssociatedObject(self, kJLActionHandlerTapBlockKey);
if (action)
{
action();
}
}
}
typedef NS_ENUM(NSInteger, JLAssociationPolicy) {
/**
OBJC_ASSOCIATION_ASSIGN < Specifies a weak reference to the associated object>
*/
JLAssociationPolicyAssign = 1,
/**
OBJC_ASSOCIATION_RETAIN_NONATOMIC <Specifies a strong reference to the associated object.
* The association is not made atomically>
*/
JLAssociationPolicyRetainNonatomic = 2,
/**
OBJC_ASSOCIATION_COPY_NONATOMIC < Specifies that the associated object is copied.
* The association is not made atomically.>
*/
JLAssociationPolicyCopyNonatomic = 3,
/**
OBJC_ASSOCIATION_RETAIN < Specifies a strong reference to the associated object.
* The association is made atomically.>
*/
JLAssociationPolicyRetain = 4,
/**
OBJC_ASSOCIATION_COPY < Specifies that the associated object is copied.
* The association is made atomically.>
*/
JLAssociationPolicyCopy = 5
};
/**
Set AssociatedObject
@param object Be Associated Object
@param key associted Key
@param value associated value or object
@param policy policy
*/+ (void)JL_setAssociatedObject:(id _Nonnull)object key:(NSString *_Nullable)key value:(id _Nullable)value policy:(JLAssociationPolicy)policy;/**
Get AssociatedObject
@param object Be Associated Object
@param key associted Key
@return associated value or object
*/+ (id _Nullable)JL_getAssociatedObject:(id _Nonnull)object key:(NSString *_Nullable)key;/**
Remove AssociatedObject
@param object associated value or object
*/+ (void)JL_removeAsociatedObject:(id _Nonnull)object;
Key,在使用的时候只需要传入NSString类的参数就可以了,不需要const void * _Nonnull key
,接口方法变得更优雅简洁一些。
//定义绑定对象的Key
static NSString *const kJLActionHandlerTapGestureKey = @"JLActionHandlerTapGestureKey";
static NSString *const kJLActionHandlerTapBlockKey = @"JLActionHandlerTapBlocKey";
- (void)setTapActionWithBlock:(void (^)(void))block
{
UITapGestureRecognizer *tapGR = [JLAssociatedObjectUtils JL_getAssociatedObject:self key:kJLActionHandlerTapGestureKey];
if (!tapGR)
{
tapGR = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(JL_handleActionForTapGesture:)];
[self addGestureRecognizer: tapGR];
[JLAssociatedObjectUtils JL_setAssociatedObject:self key:kJLActionHandlerTapGestureKey value:tapGR policy:JLAssociationPolicyRetain];
}
[JLAssociatedObjectUtils JL_setAssociatedObject:self key:kJLActionHandlerTapBlockKey value:tapGR policy:JLAssociationPolicyCopy];
}
- (void) JL_handleActionForTapGesture:(UITapGestureRecognizer *)sender
{
if (sender.state == UIGestureRecognizerStateRecognized)
{
void(^action)(void) = [JLAssociatedObjectUtils JL_getAssociatedObject:self key:kJLActionHandlerTapBlockKey];
if (action)
{
action();
}
}
}