Welcome, Guest. Please login or register.
Did you miss your activation email?
February 25, 2017, 08:47:21 AM
Home Help Search chat Login Register   
News: Read this please.The Great Kangaroo Escape Looking for reviews of the 4th ed on Amazon!   Twitter:  @skochan

+  Official Forum for Programming in Objective-C (the iPhone Programming Language) - Stephen Kochan
|-+  Programming in Objective-C, 4th edition
| |-+  Chapter 15
| | |-+  Enumerating the index set
Pages: [1]   Go Down
Print
Author Topic: Enumerating the index set  (Read 7730 times)
Eloise
Newbie
*
Posts: 8


« on: May 18, 2012, 07:34:33 AM »

The last but one paragraph suggests enumerating the IndexSet you generate to give an array of search results instead. I don't know if I was having a bad hair day or what, but it took me ages to work out how to do that. So, for anyone else who is struggling this is the method I came up with:

Code: (Objective-C)
-(NSMutableArray *)lookupAll: (NSString *)theName
{
    NSMutableArray *matches=[NSMutableArray array];
    NSIndexSet *result = [book indexesOfObjectsPassingTest: ^(id obj, NSUInteger idx, BOOL *stop)
                          {
                              if([[obj name] caseInsensitiveCompare: theName] == NSOrderedSame)
                                  return YES;
                              else
                                  return NO;
                          }];
    [result enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
        [matches addObject:[book objectAtIndex:idx]];
    }];
    return matches;
}

The middle of that (from NSIndexSet to return NO; }]; is the code given in the book.

I added the NSMutableArray *matches at the top, but you could add it after that just as easily. The clever bit is the two lines [result enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) { [matches addObject:[book objectAtIndex:idx]] }];

The first bit runs through the indexes in the IndexSet, feeding idx into the block for processing. That took me a while to figure out.

[matches addObject: is easy enough - you add new objects to your mutable array as required. I kept getting type mismatch errors until I remembered objectAtIndex: was one of the methods available to me though, which was the second chunk of time. Hope it helps.
« Last Edit: May 19, 2012, 06:40:15 AM by happyzhb » Logged
electricb
Newbie
*
Posts: 6


Email
« Reply #1 on: May 18, 2012, 07:20:44 PM »

I've tried this method and for some reason my program won't finish due to AddressCard being incompatible with NSSetIndex. I used the same program from 15.11 with the exception of the lookup method being changed to lookupAll, yet it doesn't work. Here's the code:

Code: (Objective-C)
#import "AddressBook.h"

int main(int argc, const char * argv[])
{
    
    @autoreleasepool {
        
        NSString *aName = @"Julia Kochan";
        NSString *aEmail = @"jewls337@axlc.com";
        NSString *bName = @"Tony Iannino";
        NSString *bEmail = @"tony.iannino@techfitness.com";
        NSString *cName = @"Stephen Kochan";
        NSString *cEmail = @"steve@classroomM.com";
        NSString *dName = @"Jamie Baker";
        NSString *dEmail = @"jbaker@classroomM.com";
        
        AddressCard *card1 = [[AddressCard alloc] init];
        AddressCard *card2 = [[AddressCard alloc] init];
        AddressCard *card3 = [[AddressCard alloc] init];
        AddressCard *card4 = [[AddressCard alloc] init];
        
        // Set up Address book
        
        AddressBook *myBook = [[AddressBook alloc]
                               initWithName: @"Linda's Address Book"];
        
        AddressCard *myCard;
        
        // Now set up four address cards
        
        [card1 setName: aName andEmail: aEmail];
        [card2 setName: bName andEmail: bEmail];
        [card3 setName: cName andEmail: cEmail];
        [card4 setName: dName andEmail: dEmail];
        
        // Add the cards to the address book
        
        [myBook addCard: card1];
        [myBook addCard: card2];
        [myBook addCard: card3];
        [myBook addCard: card4];
        
        // Look up a person by name  
        
        NSLog(@"Julia Kochan");  
        myCard = [myBook lookupAll: @"julia kochan"];
        if (myCard != nil)
            [myCard print];  
       else  
            NSLog(@"Not found!");  
    }
return 0;  
}

Did your code look like this,

« Last Edit: May 19, 2012, 06:39:27 AM by happyzhb » Logged
Eloise
Newbie
*
Posts: 8


« Reply #2 on: May 19, 2012, 03:14:38 AM »

I've used something like this:
Code: (Objective-C)
AddressBook *mySearch = [[AddressBook alloc] initWithName:@"Search Items"];
mySearch = [myBook lookupAll:@"a"];
[mySearch list];

To set up my searches and execute them. Seems to work just fine with everything I test it on.
Logged
electricb
Newbie
*
Posts: 6


Email
« Reply #3 on: May 19, 2012, 04:54:20 PM »

Tried what you wrote but this is what I still get the "Incompatible pointer types assigning to 'AddressBook*_strong' from 'AddressCard*' warning along with the following output with inserts a break right at the [mySearch list] line.

2012-05-19 18:52:48.947 Challenge 15.6[363:403] -[__NSArrayM list]: unrecognized selector sent to instance 0x101415530
2012-05-19 18:52:48.950 Challenge 15.6[363:403] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayM list]: unrecognized selector sent to instance 0x101415530'
*** First throw call stack:
(
   0   CoreFoundation                      0x00007fff87e30fc6 __exceptionPreprocess + 198
   1   libobjc.A.dylib                     0x00007fff8a6d8d5e objc_exception_throw + 43
   2   CoreFoundation                      0x00007fff87ebd2ae -[NSObject doesNotRecognizeSelector:] + 190
   3   CoreFoundation                      0x00007fff87e1de73 ___forwarding___ + 371
   4   CoreFoundation                      0x00007fff87e1dc88 _CF_forwarding_prep_0 + 232
   5   Challenge 15.6                      0x000000010136e500 main + 576
   6   Challenge 15.6                      0x000000010136e2b4 start + 52
)
terminate called throwing an exception(lldb)
Logged
rickyshands
Newbie
*
Posts: 8


« Reply #4 on: September 11, 2012, 12:16:47 PM »

 Huh I'm having the same problem as electricb.   I've been working on this for the last few days and I'm feeling pretty demoralized.  A clue?  Anyone?
Logged
rickyshands
Newbie
*
Posts: 8


« Reply #5 on: September 17, 2012, 02:58:28 PM »

Just to be clear, in attempting Ch.15, Exercise 5, I thought it a decent strategy to first understand the three Lookup examples at the end of the chapter.  Then I attempted to modify them until completing (I had hoped) the task of Exercise 5.  So I came up with something somewhat  similar to what Eloise did but which resulted in the same exception as that posted by electricb.   Then after much scrutiny, I just copied the posted code, and I still got the same exception as posted.  I really don't understand this exception and I could use some help, even if it's a stupid error on my part.  I'm guessing the problem falls into one of three categorical possibilities:

1)  An error arising from my fundamental lack of understanding a concept in this chapter (or possibly an earlier chapter) -- in which case, I'm sorry I'm retarded, please help me, please.
 
2)  A typo or some simple error that I'm just not catching -- in which case, please help, and I'm sorry that I'm retarded.

3)  A problem arising from something complicated and not presented in this book (possibly an Xcode or Objective-C idiosyncrasy) and nigh impossible for me to know, having scoured the internet, until some kind human just explains it to me -- in which case, please help, please.
[e.g. I really had a hard time understanding the use of  ** in "Fraction **f"
from Ch.13, E.4
until I emailed an experienced C programmer who explained that for an array, "**argv" is equivalent to "*argv[]".  Not mentioned in the book.]
[e.g. I still don't get why this is necessary:  "Fraction *__autoreleasing aF[c];"
also from Ch.13, E.4
yet it is the only way I could get Ch13, E.4 to work.  Skimmed Ch.17 but didn't find it.  Props to user Clouded though.)]

Any clue to dealing with the exception posted by ElectricB would be appreciated.

Cheers,
Rickyshands
Logged
flipyrface
Newbie
*
Posts: 5


« Reply #6 on: February 16, 2013, 11:08:53 AM »

Although I can't see your lookupAll method, I think the problem is where you try to set:
mySearch = [myBook lookupAll:@"a"];

maybe your lookupAll method returns an NSMutableArray, so mySearch is now a NSMutableArray and not an AddressBook. so, mySearch doesnt know what to do with the command "list" since its only for AddressBook objects.
Logged
anhe
Newbie
*
Posts: 12


« Reply #7 on: November 28, 2015, 07:31:51 AM »

Dear all,

this is my Version of the "lookupAll"-method:

Code: (Objective-C)
-(AddressBook *) lookupAll:(NSString *)theName
{
    AddressBook *matches = [[AddressBook alloc] initWithName:@"Search Results"];
    NSIndexSet *result = [book indexesOfObjectsPassingTest:
                          ^(id obj, NSUInteger idx, BOOL *stop)
                          {
                              if ([[obj name] caseInsensitiveCompare: theName] == NSOrderedSame) {
                                  return YES;
                              } else {
                                  return NO;
                              }
                          }];
    [result enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
        [matches addCard:[book objectAtIndex:idx]];
    }];
    return matches;
}

and the invocation within the main function:

Code: (Objective-C)
AddressBook *mySearch;
mySearch = [myBook lookupAll:@"forename surname"];
[mySearch list];

kind regards

André
Logged
Pages: [1]   Go Up
Print
Jump to:  



Login with username, password and session length

Powered by MySQL Powered by PHP Powered by SMF 1.1.11 | SMF © 2006-2009, Simple Machines LLC Valid XHTML 1.0! Valid CSS!
Entire forum contents (c) 2009 classroomM.com. All rights reserved.