我可以使用category和runtime给UIScrollView添加一个BOOL类型属性"isScrolling"吗?

Can I use category and runtime to add a BOOL type property "isScrolling" to UIScrollView?

我曾经添加一个NSString *类型属性到UIButton,但是今天,我想添加一个BOOL类型属性 isScrollingUIScrollView 以指示 scrollView 是否以相同的方式滚动但显示错误,这是我的代码:

#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

错误是:

有没有什么办法可以处理这些错误,我们可以使用类别和运行时来实现在UIScrollView中添加一个BOOL 属性来指示scrollView是否是滚动?

希望有人能给我一些建议,非常感谢。

试试这个:

尝试将布尔值转换为 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 到 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);

上面你可以看到这个值应该是object。

更改您的代码 @property (assign, nonatomic) BOOL isScrolling;@property (strong, nonatomic) NSNumber *scrolling;

并根据您的情况将 OBJC_ASSOCIATION_ASSIGN 更改为 OBJC_ASSOCIATION_RETAIN_NONATOMIC objc_setAssociatedObject(self, &strkey, scrolling, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

并使用[_scrolling boolValue]进行检查。

一个关联的对象必须只是一个对象,所以非对象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