在现有的类中添加新方法,这些新方法被称之为“类别”;
1。类别的作用
创建类别:
@interface NSString(NumberCnvenience)//声明类别 现有的类名位于@interface之后NSString,括号中是类别的名称(NumberCnvenience)
//可以理解为向NSString类中添加名称为NumberCnvenience的类别。 方法不用大括号包含在内。
-(NSNumber *) lengthAsNumber;
@end
@implementation NSString(NumberCnvenience)
-(NSNumber *) lengthAsNumber
{
unsigned int length=[selflength];
return ([NSNumbernumberWithUnsignedInt:length]);
}
@end
int main (int argc,constchar * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePoolalloc]init];
NSMutableDictionary *dict;
dict=[NSMutableDictionarydictionary];
[dictsetObject:[@"hello"lengthAsNumber]forKey:@"hello"];
[dictsetObject:[@"iLikeFish"lengthAsNumber]forKey:@"iLikeFish"];
[dictsetObject:[@"Once upon a time"lengthAsNumber]forKey:@"Once upon a time"];
NSLog(@"%@",dict);
[pool drain];
return0;
}
类别的局限性
第一:无法向类中添加新的实例变量。第二:名称冲突,即类别中的方法与现有的方法重名。当发生名称冲突时,类别具有更高的优先级。
类别的作用
将类的实现分散到多个不同文件或多个不同框架中,创建对似有方法的前向引用,以及向对象添加协议。
类别分散实现,接口放在头文件中,然后在分别去实现。在这里我添加类别的时候发现仍然有头文件,不知道这是不是3.2.5 和4.1的区别。
@interface CategoryThing :NSObject
{
int thing1;
int thing2;
int thing3;
}
@end
@interface CategoryThing (Thing1)
-(void)setThing1:(int)thing1;
-(int) thing1;
@end
@interface CategoryThing(Thing2)
-(void)setThing2:(int) thing2;
-(int) thing2;
@end
@interface CategoryThing(Thing3)
-(void)setThing3:(int) thing3;
-(int) thing3;
@end
.m文件中
-(NSString *) description
{
NSString *desc;
desc=[NSStringstringWithFormat:@"%d %d %d",thing1,thing2,thing3];
return desc;
}
Thing1.m文件
@implementation CategoryThing (Thing1)
-(void) setThing1:(int)t1
{
thing1=t1;
}
-(int)thing1
{
return thing1;
}
@end
Thing2和Thing1类似。在main函数中 导入CategoryThing.h文件
CategoryThing *things;
things=[[CategoryThingalloc]init];
[things setThing1:5];
[things setThing2:23];
[things setThing3:42];
NSLog(@"Things are %@",things);
[things release];
2。创建前向引用(不是很理解)
3。非正式协议和委托类别。
委托是把一种方法作为参数的一种方法。
-(BOOL) tableview:(NSTableView *)tableView
shouldSelectRow:(int) row;
ITunesFinder项目
@implementation ITunesFinder
-(void) netServiceBrower:(NSNetServiceBrowser *) b
didFindService:(NSNetService *)service
moreComing:(BOOL) moreComing
{
[serviceresolveWithTimeout:10];
NSLog(@"found one! Name is %@",[servicename]);
}
-(void) netServiceBrower:(NSNetServiceBrowser *) b
didRemoveService:(NSNetService *)service
moreComing:(BOOL) moreComing
{
[serviceresolveWithTimeout:10];
NSLog(@"lost one! Name is %@",[servicename]);
}
@end
int main (int argc,const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePoolalloc] init];
NSNetServiceBrowser *brower; //创建网络服务的对象。
brower=[[NSNetServiceBrowseralloc]init]; //实例化对象
ITunesFinder *finder;
finder=[[ITunesFinderalloc] init];
[brower setDelegate:finder];
[browersearchForServicesOfType:@"_daap._tcp"inDomain:@"local."];//告诉网络服务浏览器使用tcp协议去搜索DAAP类型的服务。
NSlog("begun browsing");
[[NSRunLoopcurrentRunLoop]run];//除了监听网络流量,还循环处理等待用户事件之类的其他操作。
[brower release];
[finder release];
[pool drain];
return 0;
}
3。委托和类别
@interface NSObject (NSNetServiceBrowerDelegateMethods)
-(void) netServiceBrowerWillSearch:(NSNetServiceBrowser *)brower;
-(void) netSERviceBrower:(NSNetServiceBrowser *) aNetServiceBrower
didFindService:(NSNetService *) service
moreComing:(BOOL) moreComing;
-(void) netSERviceBrower:(NSNetServiceBrowser *) aNetServiceBrower
didRemoveService:(NSNetService *) service
moreComing:(BOOL) moreComing;
@end
4。响应选择器
选择器只是一个方法名称,但它以Object-c运行时特殊的方式编码,以快速执行查询。可以使用@selector()预编译指令指定选择器。其中方法名位于选择器括号中。
@selector(setEngine:)
NSObject 提供一个名为respondsToSelector:的方法,该方法询问对象以确定其是否能够响应某个特定的消息。
Car *car1=[[Caralloc]init];
if([car1 respondsToSelector:@selector(setEngine:)])
{
NSLog(@"yowza!");
}
选择器可以被传递,可以作为方法的参数使用,甚至可以作为实例变量存储。AppKit中的NSTimer就是这样一个类,它能够反复地向一个对象发送消息。
自己对于本章内容看了几天还不是很理解。需继续在看。