1. Trang chủ >
  2. Công Nghệ Thông Tin >
  3. Kỹ thuật lập trình >

23€ Allocating and Making Use of Arrays

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (3.67 MB, 89 trang )


NSLog(@"array = %@", array);



When you run this program, you get the following text printed to your console:

array = (

"My String",

"-123",

123

)



As you can see, we used the initWithObjects: initializer of the array. When using this

initializer, pass your objects that need to be placed inside the array, one by one. At the

end, terminate the list with a nil so that the runtime knows when you are terminating

your list. If you don't do so, the LLVM Compiler will throw a warning similar to this:

warning: Semantic Issue: Missing sentinel in method dispatch



We can also use the arrayWithObjects: class method of NSArray to create an autorelease

array, like so:

NSArray *array = [NSArray arrayWithObjects:

stringObject,

signedNumber,

unsignedNumber, nil];



You can call the count method on your array to get the number of objects in that array.

You can go through your array using a for loop or using an enumerator. Let's have a

look at the solution with a for loop first:

NSArray *array = [NSArray arrayWithObjects:

stringObject,

signedNumber,

unsignedNumber,nil];

NSUInteger counter = 0;

for (counter = 0;

counter < [array count];

counter++){

id object = [array objectAtIndex:counter];

NSLog(@"Object = %@", object);

}



And here is the output:

Object = My String

Object = -123

Object = 123



As you can see, we use the objectAtIndex: method to get an object at a specific index.

Remember that indexes are zero-based. In other words, when the counter reaches -1,

the loop has to stop because there can be no negative indexes in an array.



82 | Chapter 1: The Basics



As mentioned before, you can also use fast enumeration to go through objects of an

array. Fast enumeration is a language feature in Objective-C that allows you to enumerate objects in an array or dictionary (or any other object that supports fast enumeration) without having to use any counter or for loop. The format is as follows:

for (Type variableName in array/dictionary/etc){ ... }



Support we want to code the previous example without the overhead of a counter variable. Here is how we can do it using fast enumeration:

for (id object in array){

NSLog(@"Object = %@", object);

}



The results are practically identical to the results we got from the previous version of

this code that used a counter variable.

Mutable arrays are very interesting. As you probably have already guessed, immutable

arrays cannot be modified once allocated and initialized. Mutable arrays, however,

can be modified after their allocation and initialization. Let's have a look at an example:

NSString *stringObject = @"My String";

NSNumber *signedNumber = [NSNumber numberWithInteger:-123];

NSNumber *unsignedNumber = [NSNumber numberWithUnsignedInteger:123];

NSArray *anotherArray = [[NSArray

@"String

@"String

@"String



alloc] initWithObjects:

1",

2",

3", nil];



NSMutableArray *array = [[NSMutableArray alloc] initWithObjects:

stringObject,

signedNumber, nil];

[array addObject:unsignedNumber];

[array removeObject:signedNumber];

[array addObjectsFromArray:anotherArray];

for (id object in array){

NSLog(@"Object = %@", object);

}



Before we go into analyzing the code, let's have a look at its output:

Object

Object

Object

Object

Object



=

=

=

=

=



My String

123

String 1

String 2

String 3



You might be asking, "what just happened?". Well, let's have a look what methods of

the NSMutableArray class we actually used:

addObject:



This method allows us to add an object to the end of a mutable array.



1.23 Allocating and Making Use of Arrays | 83



removeObject:



Using this method, we can remove a specific object from the array. Remember that

we pass an object to this method, not an index of the object. To remove an object

using an index into the array, we must use the removeObjectAtIndex: method.

addObjectsFromArray:



With this method, we can add objects from one array (either mutable or immutable) into our mutable array.

Please bear in mind that during fast enumeration or a mutable array,

you must not add to or remove anything from that array or you will get

a runtime error. This is the default behaviour of mutable arrays during

fast enumeration.



If you are interesting in block objects (and we'll see good reasons to be, later in the

book!), you can also enumerate objects in your arrays using the enumerateObjectsU

singBlock: method. The block object passed to this method should:

1. Return no value.

2. Have three parameters:

a. First parameter of type id, which will be the object being enumerated at each

loop of enumeration.

b. Second parameter of type NSUInteger, which will tell you the index of the current object being enumerated.

c. Last but not least, a parameter of type *BOOL, which you can use to stop the

enumeration. This is a pointer to a boolean variable which should be NO as long

as you want the enumeration to procede. You can change the value of this

pointer to YES in order to stop the enumeration at any time. You would use

this if you are looking for an object in an array and you would like to stop the

enumeration as soon as you've found that object, since there is no point continuing the enumeration if you've already found your object.

NSArray *myArray = [[NSArray

@"String

@"String

@"String

@"String



alloc] initWithObjects:

1",

2",

3",

4", nil];



[myArray enumerateObjectsUsingBlock:

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


-->

NSLog(@"Object = %@", obj);



84 | Chapter 1: The Basics



}];



If you need to sort an array, simply use the new block-based sorting methods of NSAr

ray or NSMutableArray. Just remember that the sorting methods of NSArray return a new

instance of NSArray and leave the original array intact, since NSArray cannot be modified

(sorting can modify an array) after it has been allocated and initialized. This is in comparison to the sorting methods of NSMutableArray, where the original array will be the

target of sorting and the sorting methods will not return a new array. Let's look at sorting

a mutable array:

NSMutableArray *myArray = [[NSMutableArray alloc] initWithObjects:

@"String 2",

@"String 4",

@"String 1",

@"String 3", nil];

[myArray sortUsingComparator:

^NSComparisonResult(__strong id obj1, __strong id obj2) {

NSString *string1 = (NSString *)obj1;

NSString *string2 = (NSString *)obj2;

return [string1 compare:string2];

}];

NSLog(@"myArray = %@", myArray);



The results will then be printed to the console, as follows:

myArray = (

"String

"String

"String

"String

)



1",

2",

3",

4"



So, what happened? We simply called the sortUsingComparator: method of our array.

This method takes in a block object (marked by the initial ^ character) that has to return

a value of type NSComparisonResult. This value can be any of the following:

NSOrderedSame



The two values being compared are equal.

NSOrderedAscending



The value on the left of the comparison is smaller than the value on the right. Think

of it as this: transition from value 1 (left) to value 2 (right) is ascending, meaning

that value 1 is smaller.

NSOrderedDescending



The value on the right is smaller than the value on the left. In other words, the

transition from value 1 (left) to value 2 (right) is descending, meaning that value 1

is bigger than value 2.



1.23 Allocating and Making Use of Arrays | 85



So if we get String 3 as value 1 (left) and then get String 1 as value 2 (right), is that

ascending or descending or the same? Of course, it is descending because transition

from value 1 (left, String 3) descends to value 2 (right, String 1). Remember that whichever object the compare: method gets called is the left object, or value 1.

The block object submitted to the sortUsingComparator: method takes two parameters:

First Object of type id

This is the first object in the comparison in each iteration.

Second Object of type id

This is the second object in the comparison in each iteration.

So when sorting the array, simply use a block-based approach. It's the way Apple is

pushing developers to go forward with their implementations, so it's good to know

about block objects.



See Also

XXX



1.24 Allocating and Making Use of Dictionaries

Problem

You want to store key-value pairs in an object, but arrays won't quite do it for this

purpose.



Solution

Use NSDictionary and its mutable counterpart, NSMutableDictionary



Discussion

A dictionary is a special array in which each item is given a key. That is the only difference between dictionaries and arrays. An array has a numeric index into each item/

object that it holds whereas a dictionary holds a key to each item. I'll show you what I

mean.

Let's say we want to store a person's first name, last name, and age into an array and

then into a dictionary. This is how we would store those values in an array:

NSArray *person = [[NSArray alloc] initWithObjects:

@"Anthony",

@"Robbins",

[NSNumber numberWithUnsignedInteger:51], nil];

NSLog(@"First Name = %@", [person objectAtIndex:0]);

NSLog(@"Last Name = %@", [person objectAtIndex:1]);

NSLog(@"Age = %@", [person objectAtIndex:2]);



86 | Chapter 1: The Basics



You can see that we are using an index into the array to access each one of these values.

With dictionaries, we give each value a key, which is an object, and then use that key

to access those values. Let's see the same example, using dictionaries. We have a "First

Name" key with the value "Anthony" and so on:

NSNumber *age = [NSNumber numberWithUnsignedInteger:51];

NSDictionary *person = [[NSDictionary alloc] initWithObjectsAndKeys:

@"Anthony", @"First Name",

@"Robbins", @"Last Name",

age, @"Age",

nil];

NSLog(@"First Name = %@", [person objectForKey:@"First Name"]);

NSLog(@"Last Name = %@", [person objectForKey:@"Last Name"]);

NSLog(@"Age = %@", [person objectForKey:@"Age"]);



The results will then be printed out as shown here:

First Name = Anthony

Last Name = Robbins

Age = 51



As you can see, we initialized the dictionary with values and keys. We give a value

followed by the key for that value. When we used NSLog, we printed out each value by

handing the key to the dictionary's objectForKey: method.

The mutable version of NSDictionary, NSMutableDictionary, can be modified after it has

been allocated and initialized. For instance, if we want to remove the object associated

with the key Age from our dictionary after its initialization, we would use a mutable

dictionary like so:

NSNumber *age = [NSNumber numberWithUnsignedInteger:51];

NSMutableDictionary *person = [[NSMutableDictionary alloc]

initWithObjectsAndKeys:

@"Anthony", @"First Name",

@"Robbins", @"Last Name",

age, @"Age",

nil];

[person removeObjectForKey:@"Age"];

NSLog(@"First Name = %@", [person objectForKey:@"First Name"]);

NSLog(@"Last Name = %@", [person objectForKey:@"Last Name"]);

NSLog(@"Age = %@", [person objectForKey:@"Age"]);



We have simply removed the object associated with the key Age. The results printed to

the console window will be similar to this:

First Name = Anthony

Last Name = Robbins

Age = (null)



Note that "Age" is not just empty, but totally missing.



1.24 Allocating and Making Use of Dictionaries | 87



Xem Thêm
Tải bản đầy đủ (.pdf) (89 trang)

×