避免在Category中出現(xiàn)屬性
屬性是一種數(shù)據(jù)的封裝形式弥奸,理論上來說蘑拯,你也可以在Category中聲明屬性厌衙,但是我們應(yīng)該盡量避免這樣做辜纲。
因?yàn)檫@樣做笨觅,Category是不會(huì)生成任何實(shí)例變量的拦耐,當(dāng)然也不能夠由實(shí)例變量去合成一個(gè)屬性變量的。
比如我們創(chuàng)建一個(gè)Friend的Person分類见剩,用來處理Person類中關(guān)于“Friend”的邏輯內(nèi)容杀糯,如果你像下面這樣聲明:
#import "Person.h"
@interface Person (Friendship)
@property (nonatomic, strong) NSArray *friends;
- (void)addFriend:(Person *)aFreind;
@end
編譯會(huì)得到這樣的警告:
Property 'friends' requires method 'setFriends:' to be defined - use @dynamic or provide a method implementation in this category
這個(gè)有點(diǎn)“莫名其妙”的警告的意思是無法為這個(gè)屬性生成實(shí)例變量,從而也不能合成一個(gè)屬性變量苍苞。
如果你非要在分類中聲明這個(gè)friends的數(shù)組屬性固翰,那么需要將friend聲明為@dynamic或者自己為實(shí)例變量提供setter和getter方法。將屬性聲明為dynamic意思就是告訴編譯器羹呵,自己會(huì)在runtime生成setter和getter方法骂际,讓編譯器給我們放行通過:
@implementation Person (Friendship)
@dynamic friends;
@end
另一種方法如下:
static const char *kFriendProperty = "friend";
@implementation Person (Friendship)
//@dynamic friends;
- (NSArray *)friends
{
return objc_getAssociatedObject(self, kFriendProperty);
}
- (void)setFriends:(NSArray *)friends
{
objc_setAssociatedObject(self, kFriendProperty, friends, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end
雖然通過上面的方法我們可以理論上的實(shí)現(xiàn)為Category增加屬性,但是這仍然是不推薦的冈欢,如果屬性是像NSMutableArray那樣可變的歉铝,那么處理起來就可能會(huì)更加麻煩。因此凑耻,最理想的方法還是將屬性和數(shù)據(jù)的封裝放到主類中太示。
使用類擴(kuò)展來隱藏實(shí)現(xiàn)細(xì)節(jié)
其實(shí)類擴(kuò)展,聽著很高大上拳话,只不過是下面代碼中注釋的部分先匪。
#import "Person+Friendship.h"
#import <objc/runtime.h>
//@interface Person()
//
//@end
static const char *kFriendProperty = "friend";
@implementation Person (Friendship)
- (NSArray *)friends
{
return objc_getAssociatedObject(self, kFriendProperty);
}
這個(gè)學(xué)過iOS的應(yīng)該都知道一點(diǎn)其用法,主要是用來聲明一些隱藏的變量用的弃衍。
例子如下:
#import "Person+Friendship.h"
#import <objc/runtime.h>
@interface Person()
{
NSString *_aString;
}
@end
static const char *kFriendProperty = "friend";
@implementation Person (Friendship)
//@dynamic friends;
- (NSArray *)friends
{
return objc_getAssociatedObject(self, kFriendProperty);
}
此時(shí)aStirng就作為一個(gè)“隱藏”的實(shí)例變量而不用對外暴露。
多的不多做介紹坚俗,主要總結(jié)如下
1 通過類擴(kuò)展可以向類中新增實(shí)例變量镜盯。
2 如果某屬性在主接口中聲明為“readonly”,而類的內(nèi)部又要用設(shè)置方法修改此屬性猖败,那么就在類擴(kuò)展中將其擴(kuò)展為“readwrite”速缆。
3 如果想讓類所遵循的協(xié)議不暴露在主接口,可以在類擴(kuò)展中進(jìn)行聲明恩闻。