【问题标题】:Can I use category and runtime to add a BOOL type property "isScrolling" to UIScrollView?我可以使用类别和运行时向 UIScrollView 添加 BOOL 类型属性“isScrolling”吗?
【发布时间】:2017-06-20 04:32:48
【问题描述】:

我以前在UIButton 中添加了一个NSString *type 属性,但是今天我想在UIScrollView 中添加一个BOOL 类型属性isScrolling 来指示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 是否正在滚动的目标?

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

【问题讨论】:

  • 邮政编码原样。请不要截图。
  • objc_getAssociatedObject 用于对象类型。 BOOL 不是对象类型。这就是你得到错误的原因
  • @LalKrishna 是的,我已经编辑过了。

标签: ios objective-c uiscrollview runtime categories


【解决方案1】:

关联对象 必须就是这样一个对象,因此非对象 BOOL 类型的值将不起作用,除非包装为对象。幸运的是,这很容易:

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

HTH

【讨论】:

    【解决方案2】:

    试试这个:

    尝试将布尔值转换为 nsnumber。

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

    【讨论】:

      【解决方案3】:

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

      上面可以看到value应该是object。

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

      在你的情况下将OBJC_ASSOCIATION_ASSIGN 更改为OBJC_ASSOCIATION_RETAIN_NONATOMIC objc_setAssociatedObject(self, &amp;strkey, scrolling, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

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

      【讨论】:

      • 是的,你是对的。但是我们可以处理类别中的 UIScrollView 委托,以便我们可以将值设置为“滚动”属性。我刚刚尝试过,它是无效的。你有任何想法?
      • 您可以覆盖类别中的委托方法。我可以尝试帮助您发布您的代码。
      【解决方案4】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-03
        • 2012-04-04
        • 1970-01-01
        • 1970-01-01
        • 2011-03-22
        • 2015-07-06
        相关资源
        最近更新 更多