IOS4 note 11 (4)

Equality and Comparison

 

The foregoing types will quickly come to seem to you like basic data types, but of course they are actually object types. Therefore you cannot compare them with the C operators for testing equality as you would with actual numbers. That’s because, in the case of object types, the C operators compare the pointers, not the object content of the instances. 

Similarly,  it  is up  to  individual classes  to supply ordered comparison methods. The standard  method  is  called  compare:,  and  returns  one  of  three  constants:

NSOrderedAscending (the receiver is less than the parameter),

NSOrderedSame (the receiver is equal to the parameter),

NSOrderedDescending (the receiver is greater than the parameter).

 

NSIndexSet

NSIndexSet expresses a collection of ordered  integers  (so, despite  the name,  it  isn’t really  a  set, because  a  set  is unordered). For  example, you might want  to  speak of elements 1, 2, 3, 4, 8, 9, and 10 of an NSArray. NSIndexSet expresses this notion in some compact implementation that can be readily queried. The actual implementation is opaque, but you can imagine that in this case the set might consist of two NSRange structs, (1,4) and (8,3). NSIndexSet is thus very commonly used with NSArray. For example,  to  retrieve multiple objects  simultaneously  from an array, you  specify  the

desired indexes as an NSIndexSet. It is also used with other things that are array-like; for example, you pass an NSIndexSet to a UITableView to indicate what sections to insert or delete.

An NSIndexSet  is  immutable;  its mutable  subclass  is NSMutableIndexSet. You can form a simple NSIndexSet consisting of just one contiguous range directly, by passing an NSRange to indexSetWithIndexesInRange:; but to form a more complex index set you’ll need to use NSMutableIndexSet so that you can append additional ranges.

Walking through (enumerating) the index values specified by an NSIndexSet is easy in iOS 4.0, which provides enumerateIndexesUsingBlock:. But  if your code  is to run on earlier systems, you can’t use blocks, and no enumerator is provided, so you must resort to a rather clumsy construct (Example 10-2).

Example 10-2. Enumerating an NSIndexSet

NSIndexSet* ixen = //...;

NSUInteger ix = [ixen firstIndex];

do {

    // ... do something with ix ...

} while ((ix = [ixen indexGreaterThanIndex:ix]) != NSNotFound);

 

NSArray and NSMutableArray

An NSArray is an ordered collection of objects. Its length is its count, and a particular object can be obtained by index number using objectAtIndex:. 

You can walk through (enumerate) every object in an array with the for...in construct described  in Chapter 1. (You’ll get an exception  if you try to mutate an array while enumerating it.)

You can seek an object within an array with indexOfObject: or indexOfObjectIdenticalTo:;  the  former’s  idea of equality  is  to call isEqual:, whereas  the  latter uses pointer equality.

Those familiar with other languages may miss such utility array functions as map, which builds a new array of the results of calling a method on each object in the array. (makeObjectsPerformSelector:  requires  a  selector  that  returns  no  value,  and  enumerateObjectsUsingBlock: requires a block function that returns no value.) The usual workaround is to make an empty mutable array and then enumerate the original array, calling a method and appending each result to the mutable array. It  is also sometimes possible to use key–value coding as a map substitute.

You can filter an array to produce a new array consisting of just those objects meeting a test that can be described as an NSPredicate:

NSArray* pep = [NSArray arrayWithObjects: @"Manny", @"Moe", @"Jack", nil];

NSPredicate* p = [NSPredicate predicateWithFormat:@"self BEGINSWITH[cd] 'm'"];

NSArray* ems = [pep filteredArrayUsingPredicate:p];

To filter an array on a more customized test, you can walk through the array applying the  test  and  adding  those  that  meet  it  to  an  NSMutableArray. Alternatively, in iOS 4.0 there is now the ability to filter an array using a block:

NSArray* pep = [NSArray arrayWithObjects: @"Manny", @"Moe", @"Jack", nil];

NSArray* ems =

    [pep objectsAtIndexes: [pep indexesOfObjectsPassingTest:

      ^BOOL(id obj, NSUInteger idx, BOOL *stop) {

          return ([(NSString*)obj rangeOfString:@"m"

              options:NSCaseInsensitiveSearch].location == 0);

    }]];

You can derive a sorted version of the array, supplying the sorting rules in various ways, or if it’s a mutable array, you can sort it directly.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值