数组对象(3)

3.AddressBook类

AddressBook类存储地址薄的名字和一个AddressCard的集合,将这个集合存储在一个数组对象中。要先创建一个地址薄,然后要向其中增加AddressCard,计算地址薄的记录数,列出地址薄的内容,还要搜索地址薄,删除记录,编辑现有记录,将记录排序,甚至复制记录。

AddressBook.h接口文件

#import <Foundation/Foundation.h>

#import "AddressCard.h"

@interface AddressBook : NSObject

@property (nonatomic, copy) NSString *bookName;

@property (nonatomic, strong) NSMutableArray *book;

-(id) initWithName:(NSString *) name;

-(void) addCard: (AddressCard *) theCard;

-(int) entries;

-(void) list;

@end

AddressBook.m实现文件

#import "AddressBook.h"


@implementation AddressBook

@synthesize bookName,book;

// 设置AddressBook的名称和一个空的AddressBook

-(id) initWithName:(NSString *)name

{

    self = [super init];

    if (self) {

        bookName = [NSStringstringWithString:name];

        book = [NSMutableArrayarray];

    }

    return self;

}


-(id) init

{

    return [selfinitWithName:@"NOName"];

}


-(void) addCard:(AddressCard *)theCard

{

    [book addObject: theCard];

}


-(int) entries{

    return [book count];

}


-(void ) list

{

    NSLog(@"=======Contents of:%@=======",bookName);

    for (AddressCard *theCardin book ) {

        NSLog(@"%-20s %-32s",[theCard.nameUTF8String],[theCard.email UTF8String]);

    }

    NSLog(@"================================");

}

定义的initWithName:方法返回一个id对象,而不是AddressBook对象。如果创建一个AddressBook的子类,那么initWithName:消息的接收者(以及返回值)不是AddressBook对象,它的类型使子类的类型。因此将返回类型定义为id类型。

覆写init方法能够保证:如果某人在调用alloc方法之后调用init方法,仍然可以正确的创建地址薄,而且默认的名字是“NOName”。这里的initWithName:方法是我们指定的初始化方法,目的是确保init方法会调用它。

addCard:方法将AddressCard对象作为参数,把它添加到地址薄中。

count方法返回数组元素的个数。entris方法中使用这个方法返回地址薄中的地址卡片的数目。

4.快速枚举

list方法的for循环展示一个快速枚举技术:

for (AddressCard *theCard in book ) {

        NSLog(@"%-20s %-32s",[theCard.name UTF8String],[theCard.email UTF8String]);

    }

在这里对book数组中每个元素序列使用名为快速枚举技术,它的语法非常简洁:首先定义一个能偶保留数组中每一个元素的变量(AddressCard *theCard)。使用关键字in,然后列出数组名称。当使用for循环时,它会先数组中的每一个元素赋给指定的变量,并执行循环体。然后,将第二个元素赋给变量,并执行循环体。这样一直下去,直到数组的所有元素都已经赋给变量,这样数组的每个元素都执行循环体。

注意,如果theCard已经定义为AddressCard对象,那么for循环可以变得更加简洁,语句如下:

for (theCard in book)

5.在地址薄中查询某人

现在增加一个查找方法,名称为lookup:,把需要查找的姓名作为参数。这个方法会搜索整个地址薄进行匹配,如果匹配成功,则返回这个记录,如果电话薄中不存在需要查找的姓名,则返回nil。

-(AddressCard *) lookup: (NSString *) theName

{

for (AddressCard *nextCard  in book)

if ( [nextCard.name caseInsensitiveCompare: theName] == NSOrderedSame )

return nextCard;

return nil;

}

这个方法非常简单,更好的方法可以实现部分匹配和多重匹配,比如:记录Steve Kochan、Fred stevens和steven levy都可以满足

[myBook lookup:@"steve"];

的匹配条件。有可能存在多重匹配,所以有效的方法是创建一个包含所有匹配的数组,将它返回给方法的调用者,例如:

matches = [myBook lookup:@"steve"];

6.从地址薄中删除某人

可以构造一个removeCard:方法,将指定的AddressCard从地址薄中删除,将AddressCard作为参数。

-(void) removeCard: (AddressCard *) theCard

{

[book removeObjectIdenticalTo: theCard];

}

关于什么是同一个对象,系统认为是对象位于内存中的同一个位置。所以,当两个包含相同信息的地址卡片对象处于不同的内存单元时,removeObjectIdenticalTo:方法并不会把他们视为同一个对象。所以removeObjectIdenticalTo:根据对象的地址判断两个对象是否相等。与其不同的是方法removeObject:方法根据isEqual消息判断两个对象是否相等。使用自己的方法处理相等的对象更加合理,可以编写自己的isEqual:方法。当使用removeObject:方法时,系统会调自动针对数组中的每一个调用isEqual:方法对两个元素进行比较。这个例子中,因为地址薄包含AddressCard对象作为成员,必须将isEqual方法添加到类中覆盖从NSObject继承的方法,这样可以如何确定等同性。

isEqual:方法可以这样写:

-(BOOL) isEqual: (AddressCard *) theCard

{

if ( [name isEqualToString: theCard.name] == YES  && [email isEqualToString: theCard.email] ==YES)

return YES;

else 

return NO;

}

要注意NSArray类中containsObject:和indexOfObject:方法都依赖isEqual:策略来决定两个对象是否相等。

AddressBook.h接口文件

#import <Foundation/Foundation.h>

#import "AddressCard.h"

@interface AddressBook : NSObject

@property (nonatomic, copy) NSString *bookName;

@property (nonatomic, strong) NSMutableArray *book;

-(id) initWithName:(NSString *) name;

-(void) addCard: (AddressCard *) theCard;

-(int) entries;

-(void) list;

-(AddressCard *) lookup: (NSString *)theName;

-(void) removeCard:(AddressCard *) theCard;

-(void) sort;


@end

AddressBook.m实现文件

#import "AddressBook.h"


@implementation AddressBook

@synthesize bookName,book;

// 设置AddressBook的名称和一个空的AddressBook

-(id) initWithName:(NSString *)name

{

    self = [super init];

    if (self) {

        bookName = [NSString stringWithString:name];

        book = [NSMutableArray array];

    }

    return self;

}


-(id) init

{

    return [self initWithName:@"NOName"];

}


-(void) addCard:(AddressCard *)theCard

{

    [book addObject: theCard];

}


-(int) entries{

    return [book count];

}


-(void ) list

{

    NSLog(@"=======Contents of:%@=======",bookName);

    for (AddressCard *theCard in book ) {

        NSLog(@"%-20s %-32s",[theCard.name UTF8String],[theCard.email UTF8String]);

    }

    NSLog(@"================================");

}


-(AddressCard *) lookup:(NSString *)theName

{

    for(AddressCard *nextCard in book)

        if ([nextCard.name caseInsensitiveCompare:theName] ==NSOrderedSame) {

            return nextCard;

        }

    return nil;

}


-(void) removeCard:(AddressCard *)theCard

{

    [book removeObjectIdenticalTo: theCard];

}


/*-(void) sort

{

    [book sortUsingSelector:@selector(compareNames:)];

}*/


-(void) sort

{

    [book sortUsingComparator: ^(id obj1, id obj2) {

        return [[obj1 name] compare:[obj2 name]];

    }];

}

@end



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值