Just a Computer Graphics Studio & My Life

我們自己定義的類別當然可以自訂性質 (Customize Property),但是若是SDK內建的類別,繼承其類別來自訂性質可就不建議,不過我們有特殊作法!

聽聽神人怎麼說:

The Cocoa frameworks take the approach that the Object Composition pattern is more appropriate than traditional class hierarchy.

In general, this means that there is likely to be a property on UIButton where you can set another object to handle various aspects of the button. This is the preferred way to “customize" how your button works.

One of the main reasons for this pattern is that many library components create buttons and don’t know that you want them to create instances of your subclass.

接著來實現我們的期望,也就是在SDK所定義的類別,比如UIView或UIButton上自訂性質 (Customize Property)。

首先是最重要的兩個檔(.h和.m),我們新增一個NSObject的Category,名稱為AssociatedObjectSupport。

NSObject+AssociatedObjectSupport.h

#import <Foundation/Foundation.h>

@interface NSObject (AssociatedObjectSupport)

- (void) setAssociatedObject:(id)object forKey:(char *)key;
- (id) associatedObject:(char *)key;

@end

NSObject+AssociatedObjectSupport.m

#import "NSObject+AssociatedObjectSupport.h"
#include <objc/runtime.h>

@implementation NSObject (AssociatedObjectSupport)

- (void) setAssociatedObject:(id)object forKey:(char*)key {
    objc_setAssociatedObject (self, key, object, OBJC_ASSOCIATION_RETAIN);
}

- (id) associatedObject:(char*)key {
    return (id)objc_getAssociatedObject(self, key);
}
@end

接下來是我們想增加性質 (Property)的類別,同樣是NSObject的Category,名稱我這邊取名為SafeKVO。

NSObject+SafeKVO.h

#import <Foundation/Foundation.h>

@interface NSObject (SafeKVO)

@property (nonatomic, strong) NSDictionary *infoDict;

@end

記得實作Setter和Getter。

NSObject+SafeKVO.m

#import "NSObject+SafeKVO.h"
#import "NSObject+AssociatedObjectSupport.h"

static char kSafeObserverDictionary;

@implementation NSObject (SafeKVO)

#pragma mark - Setter &amp;amp; Getter
-(void)setInfoDict:(NSDictionary *)infoDict
{
    [self setAssociatedObject:infoDict forKey:&amp;amp;kSafeObserverDictionary];
}

-(NSDictionary *)infoDict
{
    NSDictionary *dict = [self associatedObject:&amp;amp;kSafeObserverDictionary];
    
    if (![dict isKindOfClass:[NSDictionary class]]) {
        dict = [NSDictionary dictionary];
        self.infoDict = dict;
    }
    
    return dict;
}

製作完這四個檔案後,就能引入在我們想使用的地方囉~

#import "NSObject+SafeKVO.h"

- (void)viewDidLoad {
    [super viewDidLoad];
    
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    button.frame = CGRectZero;
    button.infoDict = @{@"Name" : @"HappyBoy"};
    button.tag = 7;
    
    NSLog(@"infoDict: %@", button.infoDict);
}

列印出結果是:

2015-09-12 00:18:02.575 HappyTest7[13355:456262] infoDict: {
Name = HappyBoy;
}

因為有了objc_setAssociatedObjectobjc_getAssociatedObject,讓我們想要自訂多少個性質都能隨心所欲了!

在此感謝阿宅的教學,他想要用在KVO上,所以才取名為SafeKVO:D~

參考:

Advertisements

發表留言

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

您的留言將使用 WordPress.com 帳號。 登出 / 變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 / 變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 / 變更 )

Google+ photo

您的留言將使用 Google+ 帳號。 登出 / 變更 )

連結到 %s

標籤雲

%d 位部落客按了讚: