PDA

View Full Version : @selector and sortUsingSelector




ksiedzulek
Apr 22, 2011, 06:38 AM
Hi,

I don't understand selectors. I have written this simple code and put breakpoints to look how it behave and "count" should change from 1 to 4 cause breakpoint points 4 times at count++ . Why "count" doesn't change from 1 to 4? there are three 1 and one 2 instead.

#import <Foundation/Foundation.h>


@interface AdressBook : NSObject {

NSString *bookname;
NSMutableArray *bookArray;


}

@property (nonatomic,copy) NSString *bookname;
@property (nonatomic,copy) NSMutableArray *bookArray;


-(id) initWithName: (NSString*)name;
-(void) addCard: (AdressCard*) kart;
-(void) list;
-(void) sortedList;

@end

#import "AdressCard.h"
#import "AdressBook.h"


@implementation AdressBook

@synthesize bookname, bookArray;

-(id) initWithName: (NSString*)name
{
self=[super init];
bookname=[[NSString alloc] initWithString:name];
bookArray=[[NSMutableArray alloc] init];
return self;
}
-(void) addCard: (AdressCard*) kart
{
;
}
-(void) list
{
for (AdressCard *theKart in bookArray)
NSLog(@"%@",[theKart name]);
}
-(void) sortedList
{
//int count=0;
[bookArray sortUsingSelector:@selector(compareName:)];
}





@end


#import <Foundation/Foundation.h>


@interface [B]AdressCard : NSObject {

NSString *name;
NSString *email;
int count;

}

@property (copy) NSString *name,*email;

-(void) setName: (NSString*) theName setEmail: (NSString*) theEmail;
-(NSComparisonResult) compareName: (id) element;


@end

#import "AdressCard.h"
#import "AdressBook.h"



@implementation AdressCard

@synthesize name,email;

-(void) setName: (NSString*) theName setEmail: (NSString*) theEmail
{
[self setName:theName];
[self setEmail:theEmail];
}
-(NSComparisonResult) compareName: (id) element
{
count++;
NSLog(@" ");
NSLog(@"the count number: %d", count);
NSLog(@"-------------------------");
NSLog(@"what is here?:%@", [element name]);
NSLog(@"and here: %@",[self name]);
NSLog(@"+++++++++++++++++++++++++");
NSLog(@" ");
return [name compare:(id) [element name]];



}



@end



main:

#import <Foundation/Foundation.h>
#import "AdressCard.h"
#import "AdressBook.h"

int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
AdressCard *myNewCard=[[AdressCard alloc] init];
AdressCard *mySecNewCard=[[AdressCard alloc] init];
AdressCard *myThreeNewCard=[[AdressCard alloc] init];
AdressCard *myFourNewCard=[[AdressCard alloc] init];


NSString *imie=@"Zdzisław Grabowski";
NSString *email=@"ksiedzulek@wp.pl";
NSString *imieSec=@"Pawel Zet";
NSString *emailSec=@"kbm@onet.pl";
NSString *imieThree=@"Gosia Zet";
NSString *emailThree=@"kbmG@onet.pl";
NSString *imieFour=@"Hania Zet";
NSString *emailFour=@"kbmG@onet.pl";
[myNewCard setName:imie setEmail:email];
[mySecNewCard setName:imieSec setEmail:emailSec];
[myThreeNewCard setName:imieThree setEmail:emailThree];
[myFourNewCard setName:imieFour setEmail:emailFour];

AdressBook *myBook=[[AdressBook alloc] initWithName:@"moj lancuch"];
[myBook addCard:myNewCard];
[myBook addCard:mySecNewCard];
[myBook addCard:myThreeNewCard];
[myBook addCard:myFourNewCard];
[myBook list];
[myBook sortedList];
[myBook list];



[pool drain];
return 0;
}



and here is output:

2011-04-22 13:31:35.461 Tablice[14110:a0f] Zdzisław Grabowski
2011-04-22 13:31:35.464 Tablice[14110:a0f] Pawel Zet
2011-04-22 13:31:35.464 Tablice[14110:a0f] Gosia Zet
2011-04-22 13:31:35.465 Tablice[14110:a0f] Hania Zet
2011-04-22 13:31:35.466 Tablice[14110:a0f]
2011-04-22 13:31:35.466 Tablice[14110:a0f] the count number: 1
2011-04-22 13:31:35.469 Tablice[14110:a0f] -------------------------
2011-04-22 13:31:35.470 Tablice[14110:a0f] what is here?:Pawel Zet
2011-04-22 13:31:35.471 Tablice[14110:a0f] and here: Zdzisław Grabowski
2011-04-22 13:31:35.472 Tablice[14110:a0f] +++++++++++++++++++++++++
2011-04-22 13:31:35.473 Tablice[14110:a0f]
2011-04-22 13:31:35.473 Tablice[14110:a0f]
2011-04-22 13:31:35.474 Tablice[14110:a0f] the count number: 1
2011-04-22 13:31:35.474 Tablice[14110:a0f] -------------------------
2011-04-22 13:31:35.475 Tablice[14110:a0f] what is here?:Hania Zet
2011-04-22 13:31:35.477 Tablice[14110:a0f] and here: Gosia Zet
2011-04-22 13:31:35.478 Tablice[14110:a0f] +++++++++++++++++++++++++
2011-04-22 13:31:35.479 Tablice[14110:a0f]
2011-04-22 13:31:35.479 Tablice[14110:a0f]
2011-04-22 13:31:35.480 Tablice[14110:a0f] the count number: 1
2011-04-22 13:31:35.480 Tablice[14110:a0f] -------------------------
2011-04-22 13:31:35.482 Tablice[14110:a0f] what is here?:Gosia Zet
2011-04-22 13:31:35.483 Tablice[14110:a0f] and here: Pawel Zet
2011-04-22 13:31:35.483 Tablice[14110:a0f] +++++++++++++++++++++++++
2011-04-22 13:31:35.484 Tablice[14110:a0f]
2011-04-22 13:31:35.485 Tablice[14110:a0f]
2011-04-22 13:31:35.485 Tablice[14110:a0f] the count number: 2
2011-04-22 13:31:35.486 Tablice[14110:a0f] -------------------------
2011-04-22 13:31:35.486 Tablice[14110:a0f] what is here?:Hania Zet
2011-04-22 13:31:35.487 Tablice[14110:a0f] and here: Pawel Zet
2011-04-22 13:31:35.488 Tablice[14110:a0f] +++++++++++++++++++++++++
2011-04-22 13:31:35.488 Tablice[14110:a0f]
2011-04-22 13:31:35.489 Tablice[14110:a0f] Gosia Zet
2011-04-22 13:31:35.489 Tablice[14110:a0f] Hania Zet
2011-04-22 13:31:35.490 Tablice[14110:a0f] Pawel Zet
2011-04-22 13:31:35.490 Tablice[14110:a0f] Zdzisław Grabowski



gnasher729
Apr 22, 2011, 07:39 AM
Hi,

I don't understand selectors. I have written this simple code and put breakpoints to look how it behave and "count" should change from 1 to 4 cause breakpoint points 4 times at count++ . Why "count" doesn't change from 1 to 4? there are three 1 and one 2 instead.


Your problem has nothing to do with selectors at all. "count" is a member variable. That means every object has its own "count" member. You have four breakpoints, and each time _one_ of the several "count" members is increased, but not always the same one. If you add the "count" members of all objects, their sum will be four.

jiminaus
Apr 22, 2011, 07:42 AM
You're not counting the total number of comparisons made to sort your address book, you're counting the number of times each address card is asked to compare itself to another address card.

So what you're see is that each card is asked to comparison itself once with another card. This is the 1's. Except at the end, the address card for Hania Zet
it also asked to comparison itself with the address card for Pawel Zet hence the last count of 2.

Why?

The reason has nothing to do with the @selector. The reason has everything to do with the fact you've put count in as an instance variable of AddressCard. So each AddressCard is storing the number of times it has been send a compare compareName: messsage.

If you want to count the total number of comparisons being made, you need to move count out of AddressCard and into a (file static) global variable.


#import <Foundation/Foundation.h>

@interface AdressCard : NSObject {

NSString *name;
NSString *email;
// int count;

}

@property (copy) NSString *name,*email;

-(void) setName: (NSString*) theName setEmail: (NSString*) theEmail;
-(NSComparisonResult) compareName: (id) element;

@end



#import "AdressCard.h"
#import "AdressBook.h" // Why?

static int count = 0;

@implementation AdressCard

@synthesize name,email;

-(void) setName: (NSString*) theName setEmail: (NSString*) theEmail
{
[self setName:theName];
[self setEmail:theEmail];
}
-(NSComparisonResult) compareName: (id) element
{
count++;
NSLog(@" ");
NSLog(@"the count number: %d", count);
NSLog(@"-------------------------");
NSLog(@"what is here?:%@", [element name]);
NSLog(@"and here: %@",[self name]);
NSLog(@"+++++++++++++++++++++++++");
NSLog(@" ");
return [name compare:(id) [element name]];
}

@end

ksiedzulek
Apr 22, 2011, 09:50 AM
thanks for quick, great reply Guys!

but...

Your problem has nothing to do with selectors at all.


I've thought that the reason why breakpoints point 4 times at count++ is because of selector:


-(void) sortedList
{
//int count=0;
[bookArray sortUsingSelector:@selector(compareName:)];
}

-(NSComparisonResult) compareName: (id) element
{
count++;
NSLog(@" ");
NSLog(@"the count number: %d", count);
NSLog(@"-------------------------");
NSLog(@"what is here?:%@", [element name]);
NSLog(@"and here: %@",[self name]);
NSLog(@"+++++++++++++++++++++++++");
NSLog(@" ");
return [name compare:(id) [element name]];



}

I put breakpoints because I wonder what happen with this code during debugging. Now I know that code go 4 times through "-(NSComparisonResult) compareName: (id) element", but I still don't know why my program know that he must make a "loop"? and if I call these method:
[bookArray sortUsingSelector:@selector(compareName: )]
program knows what put as a argument here:
-(NSComparisonResult) compareName: (id) element
..and he knows that (for my array) for 4 times..

..why? because of @selector?

gnasher729
Apr 22, 2011, 01:05 PM
Well, it has nothing to do with the fact that this particular method has a selector as a parameter, it has to do with the fact that the sort code needed to perform four comparisons between elements of the array. There are functions ike qsort which takes a function pointer, or qsort_b which takes a block parameter; they would call their comparison code four times with this data just as sortUsingSelector.

Let's play a game. I have four different numbers a, b, c and d. You have to sort them, but I don't tell you what the values are. If you ask me which of two numbers (for example a and d) is the smaller one, I will tell you. How many questions do you have to ask?

ksiedzulek
Apr 22, 2011, 08:20 PM
I think 4 times...:)