开发者

NSComparator in Separate File

开发者 https://www.devze.com 2023-03-28 00:02 出处:网络
I have a sorting comparator which I need to use in a few different ViewControllers so I\'m trying to keep it in a separate file. I\'ve read I should be able to put the sorting block in a separate file

I have a sorting comparator which I need to use in a few different ViewControllers so I'm trying to keep it in a separate file. I've read I should be able to put the sorting block in a separate file, but which ever method I try I seem to get "unrecognized selector sent to instance". The code I have is:

#import <Foundation/Foundation.h>

typedef NSComparator (^IntBlock)(id obj1, id obj2);

@interface Utils : NSObject {
    NSComparator SortObjNameComparer;
    NSComparator SortObjPriceComparer;
}
@property (readw开发者_如何学运维rite, copy) NSComparator SortObjNameComparer;
@property (readwrite, copy) NSComparator SortObjPriceComparer;

To sort this I'm using

Utils *comp = [[Utils alloc] init];
if(segmentedControl.selectedSegmentIndex == 0){
    self.productArray = [self.productArray sortedArrayUsingComparator:[comp SortObjNameComparer] context:nil];   //EXC_BAD_ACCESS     
} else if(segmentedControl.selectedSegmentIndex == 1){
    self.productArray = [self.productArray sortedArrayUsingComparator:[Utils SortObjPriceComparer]];// EXC_BAD_ACCESS

Is there a clean way to do this?


Why are you declaring IntBlock as a block that returns an NSComparator, I do not believe you will need that at all. Also blocks are allocated on the stack by default so make sure when you initialize the properties you do so correctly. If you post the initialization of your block it would help to answer your question but your implementation should look similar to this.

-(id)init
{
    if((self = [super init]))
    {
        //Make sure you use self.
        self.SortObjNameComparer = ^(id obj1, id obj2){ return NSOrderedSame; };
        self.SortObjPriceComparer = ^(id obj1, id obj2){ return NSOrderedSame; };
    }
    return self;
}

-(void)dellaoc
{
    Block_release(SortObjNameComparer);
    Block_release(SortObjPriceComparer);

    [super dealloc];
}


Another way to do this is to create a C function that returns a block. That way you can create this block wherever you like:

e.g

MyComparator.h

#import <Foundation/Foundation.h>

NSComparator CreateObjNameComparer(void);
NSComparator CreateObjPriceComparer(void);

MyComparator.m

#import MyComparator.h

NSComparator CreateObjNameComparer(void) {
    NSComparator myComparator = ^(id obj1, id obj2) {
        // Your definition here
    };
    return Block_copy(myComparator);
}

NSComparator CreateObjPriceComparer(void) {
    NSComparator myComparator = ^(id obj1, id obj2) {
        // Your definition here
    };
    return Block_copy(myComparator);
}

And then all you need to do it use these is to import the header and use it as:

NSComparator nameComparator = CreateObjNameComparor();
// Use the block
Block_release(nameComparator);

Saves having to go through the whole Object creation and property route.

Note that I'm using the Create naming convention to remind me that I have to release the object myself when I'm done with it.

0

精彩评论

暂无评论...
验证码 换一张
取 消