一句話筆記详恼,某段時(shí)間內(nèi)遇到或看到的某個(gè)可記錄的點(diǎn)补君。 2016-8-10
- 一個(gè)獲取KVO keyPath 的宏
- Category 可以聲明屬性,但是由于不能生成實(shí)例變量昧互,才等同于不能添加屬性
- 刪除字符串的前后空格(NSCharacterSet)
- NSProxy 初探
1挽铁、一個(gè)獲取KVO keyPath 的宏
#define YSGetKVOKeyPath(objc,keyPath) @(((void)objc.keyPath,#keyPath))
[self.tableView addObserver:self forKeyPath:YSGetKVOKeyPath(self.tableView, contentOffset) options:NSKeyValueObservingOptionNew context:nil];
[self.tableView removeObserver:self forKeyPath:YSGetKVOKeyPath(self.tableView, contentOffset)];
這樣我們就不需要擔(dān)心,寫的麻煩或者說直接寫路徑名 出現(xiàn)拼寫錯(cuò)誤的的情況啦敞掘。
2叽掘、 Category 可以聲明屬性,但由于不生成實(shí)例變量玖雁,才等同于不能生成屬性
通常我們常說 Category 內(nèi)是不能直接添加屬性的更扁,我很好奇的去再嘗試下,發(fā)現(xiàn)是可以聲明屬性的赫冬,問題來了浓镜,那為什么我們通常說的不能添加屬性呢。
// .h
@property (nonatomic, copy) NSString *testName;
// .m
- (NSString *)testName {
return _testName;
}
上述這種情況劲厌,正常來說是可以return _testName
膛薛,但是在Category 里面是不可以哦,經(jīng)查找資料發(fā)現(xiàn)补鼻,在動(dòng)態(tài)添加成員變量的時(shí)候哄啄,是有限制的。
在Objective-C提供的runtime函數(shù)中风范,確實(shí)有一個(gè)class_addIvar()函數(shù)用于給類添加成員變量咨跌,但是文檔中特別說明:
This function may only be called after objc_allocateClassPair and before objc_registerClassPair. Adding an instance variable to an existing class is not supported.
表面這個(gè)函數(shù)只能在“構(gòu)建一個(gè)類的過程中”調(diào)用。一旦完成類定義硼婿,就不能再添加成員變量了虑润。經(jīng)過編譯的類在程序啟動(dòng)后就runtime
加載,沒有機(jī)會(huì)調(diào)用addIvar
加酵。
再回過頭來來拳喻,記住
@property = ivar + getter + setter;
“屬性” (property) 作為 Objective-C 的一項(xiàng)特性哭当,主要的作用就在于封裝對(duì)象中的數(shù)據(jù)。 Objective-C 對(duì)象通常會(huì)把其所需要的數(shù)據(jù)保存為各種實(shí)例變量冗澈。實(shí)例變量一般通過“存取方法”(access method)來訪問钦勘。其中,“獲取方法” (getter
) 用于讀取變量值亚亲,而“設(shè)置方法” (setter
)用于寫入變量值彻采。
詳細(xì)的說:我們每次在增加一個(gè)屬性,系統(tǒng)都會(huì)在 ivar_list
中添加一個(gè)成員變量的描述,在 method_list
中增加setter
與 getter
方法的描述,在屬性列表中增加一個(gè)屬性的描述,然后計(jì)算該屬性在對(duì)象中的偏移量,然后給出 setter
與 getter
方法對(duì)應(yīng)的實(shí)現(xiàn),在setter
方法中從偏移量的位置開始賦值,在 getter
方法中從偏移量開始取值,為了能夠讀取正確字節(jié)數(shù),系統(tǒng)對(duì)象偏移量的指針類型進(jìn)行了類型強(qiáng)轉(zhuǎn).
來自@property 的本質(zhì)是什么?ivar捌归、getter肛响、setter 是如何生成并添加到這個(gè)類中的
在類別中聲明屬性只是相等于聲明了
setter
和getter
方法,但是沒有實(shí)現(xiàn)惜索,而實(shí)現(xiàn)需要實(shí)例變量配合特笋。
所以這整個(gè)過程走不完,所以要真正的生成屬性需要用到objc_setAssociatedObject
和objc_getAssociatedObject
關(guān)聯(lián)對(duì)象啦巾兆。
3猎物、刪除字符串的前后空格(NSCharacterSet)
直接做法,同時(shí)還只是刪除前后一個(gè)空格的
- (NSString *)cutLeadAndTrialOneBlankCharacter:(NSString *)string {
NSMutableString *resultString = [NSMutableString string];
if (string.length > 2) {
// 第一個(gè) BlankCharacter
if ([[resultString substringToIndex:1] isEqualToString:@" "]) {
[resultString deleteCharactersInRange:NSMakeRange(0, 1)];
}
// 最后一個(gè) BlankCharacter
if ([[resultString substringFromIndex:resultString.length - 1] isEqualToString:@" "]) {
[resultString deleteCharactersInRange:NSMakeRange(resultString.length - 1, 1)];
}
}
return resultString.copy;
}
NSCharacterSet 的做法角塑,去除前后的空格 + 回車 或 去除前后的空格
[NSCharacterSet whitespaceAndNewlineCharacterSet];
[NSCharacterSet whitespaceCharacterSet];
- (NSString *)cutLeadAndTrialBlankCharacter:(NSString *)string {
NSString *resultString = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; //去除前后的空格 + 回車
// NSString *resultString = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; // 去除前后的空格
return resultString;
}
注意多了解些 NSCharacterSet 會(huì)有很多意想不到的效果哦蔫磨。
4、NSProxy 初探
今天看到NSProxy——少見卻神奇的類 這篇文章后圃伶,發(fā)現(xiàn)對(duì) NSProxy 這個(gè)了解確實(shí)很模糊堤如,雖說可能暫時(shí)不用,但是其用法還是有一個(gè)印象好窒朋。
言簡(jiǎn)意賅: NSProxy是NSObject的一個(gè)虛類搀罢,目的為了來“代理”一個(gè)真實(shí)對(duì)象的。我們可以讓NSProxy的實(shí)現(xiàn)類能夠很好地“代理”NSObject子類炼邀,并且把NSObject協(xié)議抽象出來魄揉,讓他們能夠共享某些行為剪侮。
@interface NSProxy <NSObject>
具體用處: 我們可以通過繼承它拭宁,并重寫這兩個(gè)方法以實(shí)現(xiàn)消息轉(zhuǎn)發(fā)到另一個(gè)實(shí)例。
用到的就是
// 方法參數(shù)代表未知的選擇子瓣俯,若當(dāng)前接收者能找到備援對(duì)象杰标,則將其返回,若找不到彩匕,就返回nil腔剂。
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel;
// 完整的消息轉(zhuǎn)發(fā)
- (void)forwardInvocation:(NSInvocation *)anInvocation;
再次翻看之前的一個(gè)筆記有效方法12-理解消息轉(zhuǎn)發(fā)機(jī)制,重新理解這個(gè)過程驼仪,另外具體的實(shí)現(xiàn)可以看看 NSProxy——少見卻神奇的類 中的 Demo 的用法掸犬。