我可以使用类别和运行时将一个BOOL类型属性“isScrolling”添加到UIScrollView吗?
我用一个NSString *
类型属性添加到UIButton
,但是今天,我想一个BOOL
type属性isScrolling
添加到UIScrollView
指示滚动视图是否以同样的方式滚动但表现有些不对劲,这里是我的代码:我可以使用类别和运行时将一个BOOL类型属性“isScrolling”添加到UIScrollView吗?
#import <UIKit/UIKit.h>
@interface UIScrollView (Util)
@property (nonatomic,assign) BOOL isScrolling;
@end
#import <objc/objc-runtime.h>
@interface UIScrollView()<UIScrollViewDelegate>
@end
@implementation UIScrollView (Util)
static void *strKey = &strKey;
- (void)setIsScrolling:(BOOL)isScrolling{
objc_setAssociatedObject(self, & strKey, isScrolling, OBJC_ASSOCIATION_ASSIGN);
}
- (BOOL)isScrolling{
return objc_getAssociatedObject(self, &strKey);
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
self.isScrolling = YES;
}
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView{
self.isScrolling = NO;
}
@end
有什么办法对付thses错误,我们可以使用类别和运行时,实现添加BOOL
属性UIScrollView
的目标指示whethe滚动视图滚动?
希望有人能给我一些建议,非常感谢。
由于错误显示BOOL为ID的隐式转换,你需要发送一个对象,而不是原始类型。
为objc_setAssociatedObject方法签名为
/**
* Sets an associated value for a given object using a given key and association policy.
*
* @param object The source object for the association.
* @param key The key for the association.
* @param value The value to associate with the key key for object. Pass nil to clear an existing association.
* @param policy The policy for the association. For possible values, see “Associative Object Behaviors.”
*
* @see objc_setAssociatedObject
* @see objc_removeAssociatedObjects
*/
OBJC_EXPORT void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)
OBJC_AVAILABLE(10.6, 3.1, 9.0, 1.0);
上面可以看到该值应为对象。
代码 @property (assign, nonatomic) BOOL isScrolling;
更改为@property (strong, nonatomic) NSNumber *scrolling;
对你来说objc_setAssociatedObject(self, &strkey, scrolling, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
改变OBJC_ASSOCIATION_ASSIGN
到OBJC_ASSOCIATION_RETAIN_NONATOMIC
而使用[_scrolling boolValue]
检查。
是的,你是对的。但是我们可以在类别中处理UIScrollView委托,以便我们可以将值设置为“滚动”属性。我刚刚尝试过,它是无效的。您有任何想法吗? –
您可以覆盖类别中的委托方法。我可以试着帮你发布你的代码。 – Tabz
试试这个:
尝试将boolean转换为nsnumber。
-(void)setIsScrolling:(BOOL)isScrolling{
objc_setAssociatedObject(self, & strkey), [NSNumber numberWithBool:isScrolling], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
不能将原始数据类型设置为AssociatedObject
,它是一个对象。当您保存数据时,将bool
转换为NSNumber
。读取数据时将NSNumber
转换为bool
。
OBJC_ASSOCIATION_ASSIGN
- 指定对关联对象的弱引用。 OBJC_ASSOCIATION_RETAIN_NONATOMIC
- 指定对关联对象的强引用,并且关联不是自动创建的。
.h文件中:
#import <UIKit/UIKit.h>
@interface UIScrollView (ScrollViewCategory)
@property (nonatomic, strong)NSNumber *isScrolling;
@end
.m文件
@interface UIScrollView()
@end
#import <objc/runtime.h>
@implementation UIScrollView (ScrollViewCategory)
@dynamic isScrolling;
- (void)setAssociatedObject:(id)object {
objc_setAssociatedObject(self, @selector(associatedObject), object, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (id)associatedObject {
return objc_getAssociatedObject(self, @selector(associatedObject));
}
一种相关联的对象必须只是,一个对象,并且因此非对象BOOL
类型的值将不工作,除非包装成一个对象。幸运的是很容易的:
- 在调用
objc_setAssociatedObject
变化isScrolling
到@(isScrolling)
和更改OBJC_ASSOCIATION_ASSIGN
到OBJC_ASSOCIATION_RETAIN_NONATOMIC
。这将创建并传递一个NSNumber
对象,第二个更改请求将此对象的生命周期与第一个参数self
的生命周期绑定在一起。 -
isScrolling
变更objc_getAssociatedObject(self, &strKey)
变为[objc_getAssociatedObject(self, &strKey) boolValue]
。这将从存储的NSNumber
对象中提取BOOL
值。
HTH
后的代码,因为它是。请不要截图。 –
objc_getAssociatedObject用于对象类型。 BOOL不是对象类型。这就是为什么你得到了错误 –
@Lkrishna是的,我编辑过。 –