正如Josh指出的那樣,除非您打電話給他們,否則添加在類別中的任何方法基本上都是惰性的。我遇到的問題是生成的屬性和類別中混雜的方法(因爲Josh也指出Objective-C中沒有混入)。
我能夠通過在我的類別中添加一個自定義BOOL
來解決此問題,該類別默認爲NO
,並充當我要指定的任何類別方法和屬性的「開關」。
E.g.,如果我想懶洋洋地實例化我dictionary
財產,但只在MyCustomView
,我能做到以下幾點:
// UIView+Dictionary.h
@interface UIView (Dictionary)
@property (nonatomic) BOOL enableDictionary;
@property (nonatomic, strong) NSDictionary *dictionary;
@end
// UIView+Dictionary.m
#import "UIViewController+CustomNavigationBar.h"
#import <objc/runtime.h>
@implementation UIView (Dictionary)
- (void)setEnableDictionary:(BOOL)enableDictionary {
objc_setAssociatedObject(self, @selector(enableDictionary), @(enableDictionary), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (BOOL)enableDictionary {
NSNumber *enableDictionaryValue = objc_getAssociatedObject(self, @selector(enableDictionary));
if (enableDictionaryValue) {
return enableDictionaryValue.boolValue;
}
objc_setAssociatedObject(self, @selector(enableDictionary), @NO, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
return self.enableDictionary;
}
- (void)setDictionary:(NSDictionary *)dictionary {
objc_setAssociatedObject(self, @selector(dictionary), dictionary, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (NSDictionary *)dictionary {
if (!self.enableDictionary) {
return nil;
}
NSDictionary *dictionary = objc_getAssociatedObject(self, @selector(dictionary));
if (dictionary) {
return dictionary;
}
objc_setAssociatedObject(self, @selector(dictionary), @{}, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
return self.dictionary;
}
@end
然後內-[MyCustomView viewDidLoad]
我可以簡單地叫self.enableDictionary = YES
。這樣,只有MyCustomView的實例纔會有非零的延遲實例化的NSDictionary。 (需要注意的是,在這個例子中,UIViews的所有實例仍然會迴應選擇@selector(dictionary)
,但我們的行爲會有所不同基於enableDictionary
是YES
或NO
。)
雖然這是一個簡單的例子,同樣的策略可以用於在類別中混用的方法。 (同樣,類別內的混合方法可能是不好的形式,但在某些情況下是必要的惡魔。)
謝謝,這是我懷疑的。我想我必須複製粘貼整個類別實現爲每個特定的類,然後我想要它應用?例如,如果我有'MyUIViewSubclassOne'和'MyUIViewSubclassTwo'(因爲類別不是可繼承的AFAIK)。 –
是的,ObjC中沒有混入,所以如果你不能識別一個超類來放置類別,你必須明確地將它添加到它們中。但是,可以只在一個地方定義方法,並使用運行時庫將它們添加到類中。我也想知道爲什麼這些方法不適用於UIView是非常重要的:它們基本上是惰性的,除非您專門使用它們。雖然它們存在,但只有你的代碼知道這一點。 –
攪拌方法x_x –