zoukankan      html  css  js  c++  java
  • iOS学习系列 扩展机制category与associative

    category与associative作为objective-c的扩展机制的两个特性,category即类型,可以通过它来扩展方法;associative,可以通过它来扩展属性;在iOS开发中,可能category比较常见,相对的associative,就用的比较少,要用它必须使用<objc/runtime.h>的头文件,然后就可以自由使用objc_getAssociatedObject以及objc_setAssociatedObject,我们来看下这两个方法:

    OBJC_EXPORT void objc_setAssociatedObject(id objectconst void *key, id value, objc_AssociationPolicy policy)
    __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_1);
    OBJC_EXPORT id objc_getAssociatedObject(id objectconst void *key)
    __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_1);

    另外还有一个方法:

    OBJC_EXPORT void objc_removeAssociatedObjects(id object)
    __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_1);

    objc_getAssociatedObject、objc_setAssociatedObject、objc_removeAssociatedObjects都是Obj-c中的外联方法,object 参数作为待扩展的对象实例,key作为该对象实例的属性的键,而value就是对象实例的属性的值,policy作为关联的策略,它的枚举包括:

    enum {
    OBJC_ASSOCIATION_ASSIGN = 0,
    OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1,
    OBJC_ASSOCIATION_COPY_NONATOMIC = 3,
    OBJC_ASSOCIATION_RETAIN = 01401,
    OBJC_ASSOCIATION_COPY = 01403
    };

    具体我就多说了,可以看得懂的。

    另外,objc_removeAssociatedObjects可以删除指定对象实例的所有扩展属性。

    现在看一个简单的例子:(引用网上的例子:http://code4app.com/ios/Block-UI/504fe65d6803faa33f000003 )

    201209122351.jpg

    这里,定义了一个"alert view"的按钮:

    UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    [viewController.view addSubview:button];
    button.frame = CGRectMake(505010044);
    [button setTitle:@"alert view" forState:UIControlStateNormal];

    现在对UIButton通过使用category对其进行方法扩展:

    @implementation UIControl (BUIControl)
    …...
    - (void)handleControlEvent:(UIControlEvents)event withBlock:(void(^)(id sender))block {
    NSString *methodName = [UIControl eventName:event];
    NSMutableDictionary *opreations = (NSMutableDictionary*)objc_getAssociatedObject(self, &OperationKey);
    if(opreations == nil)
    {
    opreations = [[NSMutableDictionary alloc] init];
    objc_setAssociatedObject(self, &OperationKey, opreations, OBJC_ASSOCIATION_RETAIN);
    }
    [opreations setObject:block forKey:methodName];
    [self addTarget:self action:NSSelectorFromString(methodName) forControlEvents:event];
    }

    objc_getAssociatedObject,objc_setAssociatedObject进行属性扩展:

    OperationKey是一个字符类型,这里表示一个键,如果Opreations为空,会setAssociatedObject一个新的opreations对象到对应键的值中间。

    addTarget:action:forControlEvents对于触摸事件进行目标绑定。

    NSSelectorFromString(methodName) 将触发方法:

    -(void)UIControlEventTouchDown{[self callActionBlock:UIControlEventTouchDown];}
    -(void)UIControlEventTouchDownRepeat{[self callActionBlock:UIControlEventTouchDownRepeat];}
    -(void)UIControlEventTouchDragInside{[self callActionBlock:UIControlEventTouchDragInside];}
    -(void)UIControlEventTouchDragOutside{[self callActionBlock:UIControlEventTouchDragOutside];}
    -(void)UIControlEventTouchDragEnter{[self callActionBlock:UIControlEventTouchDragEnter];}
    -(void)UIControlEventTouchDragExit{[self callActionBlock:UIControlEventTouchDragExit];}
    -(void)UIControlEventTouchUpInside{[self callActionBlock:UIControlEventTouchUpInside];}
    -(void)UIControlEventTouchUpOutside{[self callActionBlock:UIControlEventTouchUpOutside];}
    -(void)UIControlEventTouchCancel{[self callActionBlock:UIControlEventTouchCancel];}
    -(void)UIControlEventValueChanged{[self callActionBlock:UIControlEventValueChanged];}
    -(void)UIControlEventEditingDidBegin{[self callActionBlock:UIControlEventEditingDidBegin];}
    -(void)UIControlEventEditingChanged{[self callActionBlock:UIControlEventEditingChanged];}
    -(void)UIControlEventEditingDidEnd{[self callActionBlock:UIControlEventEditingDidEnd];}
    -(void)UIControlEventEditingDidEndOnExit{[self callActionBlock:UIControlEventEditingDidEndOnExit];}
    -(void)UIControlEventAllTouchEvents{[self callActionBlock:UIControlEventAllTouchEvents];}
    -(void)UIControlEventAllEditingEvents{[self callActionBlock:UIControlEventAllEditingEvents];}
    -(void)UIControlEventApplicationReserved{[self callActionBlock:UIControlEventApplicationReserved];}
    -(void)UIControlEventSystemReserved{[self callActionBlock:UIControlEventSystemReserved];}
    -(void)UIControlEventAllEvents{[self callActionBlock:UIControlEventAllEvents];}

    注意到这里会去执行callActionBlock:方法:

    - (void)callActionBlock:(UIControlEvents)event {
    NSMutableDictionary *opreations = (NSMutableDictionary*)objc_getAssociatedObject(self, &OperationKey);
    if(opreations == nil) return;
    void(^block)(id sender) = [opreations objectForKey:[UIControl eventName:event]];
    if (block) block(self);
    }

    最终会从扩展属性中得到^block,关于^block可以参考:http://blog.csdn.net/pjk1129/article/details/6577097

    最后调用:

    [button handleControlEvent:UIControlEventTouchUpInside withBlock:^(id sender) {
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"alert"
    message:nil
    delegate:nil
    cancelButtonTitle:@"ok"
    otherButtonTitles:@"other",nil];
    }];

    点击按钮就会触发一个block函数。

    201209130006.jpg

    这样就实现了objective-c的两种扩展机制。

  • 相关阅读:
    leetcode Remove Linked List Elements
    leetcode Word Pattern
    leetcode Isomorphic Strings
    leetcode Valid Parentheses
    leetcode Remove Nth Node From End of List
    leetcode Contains Duplicate II
    leetcode Rectangle Area
    leetcode Length of Last Word
    leetcode Valid Sudoku
    leetcode Reverse Bits
  • 原文地址:https://www.cnblogs.com/liping13599168/p/2682664.html
Copyright © 2011-2022 走看看