我可以使用类别和运行时将BOOL类型属性“isScrolling”添加到UIScrollView吗?

时间:2017-06-20 04:32:48

标签: ios objective-c uiscrollview runtime categories

我以前向NSString *添加了UIButton类型的属性,但是今天我要向BOOL添加isScrolling类型属性UIScrollView来表示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

错误是: enter image description here

有没有办法处理这些错误,我们可以使用类别和运行时来实现向BOOL添加UIScrollView属性以指示scrollView是否滚动的目标吗?

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

4 个答案:

答案 0 :(得分:1)

关联对象必须只是一个对象,因此除非作为对象包装,否则非对象BOOL类型的值不会起作用。幸运的是,这很简单:

  • 在致电objc_setAssociatedObject时,将isScrolling更改为@(isScrolling)并将OBJC_ASSOCIATION_ASSIGN更改为OBJC_ASSOCIATION_RETAIN_NONATOMIC。这将创建并传递NSNumber对象,第二个更改请求将此对象的生命周期与第一个参数self的生命周期绑定。
  • isScrollingobjc_getAssociatedObject(self, &strKey)更改为[objc_getAssociatedObject(self, &strKey) boolValue]。这将从存储的BOOL对象中提取NSNumber值。

HTH

答案 1 :(得分:0)

试试这个:

尝试将布尔值转换为nsnumber。

  -(void)setIsScrolling:(BOOL)isScrolling{
        objc_setAssociatedObject(self, & strkey), [NSNumber numberWithBool:isScrolling], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }

答案 2 :(得分:-1)

您无法将基元数据类型设置为.menu{ height: auto; max-height: 800px; overflow: auto; overflow-x: hidden; } ,它是一个对象。保存数据时,将AssociatedObject转换为bool。在阅读数据时将NSNumber转换为NSNumber

bool - 指定对关联对象的弱引用。 OBJC_ASSOCIATION_ASSIGN - 指定对关联对象的强引用,并且不以原子方式创建关联。

.h文件:

OBJC_ASSOCIATION_RETAIN_NONATOMIC

.m文件

#import <UIKit/UIKit.h>

@interface UIScrollView (ScrollViewCategory)

@property (nonatomic, strong)NSNumber *isScrolling;

@end

答案 3 :(得分:-1)

由于错误显示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_ASSOCIATION_ASSIGN

中将OBJC_ASSOCIATION_RETAIN_NONATOMIC更改为objc_setAssociatedObject(self, &strkey, scrolling, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

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