2017-06-20 78 views
1

我用一个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 

和错误是: enter image description here

有什么办法对付thses错误,我们可以使用类别和运行时,实现添加BOOL属性UIScrollView的目标指示whethe滚动视图滚动?

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

+0

后的代码,因为它是。请不要截图。 –

+0

objc_getAssociatedObject用于对象类型。 BOOL不是对象类型。这就是为什么你得到了错误 –

+0

@Lkrishna是的,我编辑过。 –

回答

-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_setAssociatedObject(self, &strkey, scrolling, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

改变OBJC_ASSOCIATION_ASSIGNOBJC_ASSOCIATION_RETAIN_NONATOMIC而使用[_scrolling boolValue]检查。

+0

是的,你是对的。但是我们可以在类别中处理UIScrollView委托,以便我们可以将值设置为“滚动”属性。我刚刚尝试过,它是无效的。您有任何想法吗? –

+0

您可以覆盖类别中的委托方法。我可以试着帮你发布你的代码。 – Tabz

0

试试这个:

尝试将boolean转换为nsnumber。

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

不能将原始数据类型设置为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)); 
} 
1

一种相关联的对象必须只是,一个对象,并且因此非对象BOOL类型的值将不工作,除非包装成一个对象。幸运的是很容易的:

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

HTH

相关问题