3

I have an NSMutableOrderedSet.

I need to enumerate it, and it looks like the only options built onto the set are block based. So picking the simplest of the block based options, I have something like this...

[anNSMutableOrderedSet enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
    if ([(SomeClass*)obj isWhatIWant]) {
        *stop = YES;
        // Ok, found what I'm looking for, but how do I get it out to the rest of the code?        
    }
}]
Logicsaurus Rex
  • 3,172
  • 2
  • 18
  • 27

4 Answers4

4

You can use __block to assign some value inside completion block.

__block yourClass *yourVariable;
[anNSMutableOrderedSet enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
    if ([(SomeClass*)obj isWhatYouWant]) {
        yourVariable = obj;
        *stop = YES; 
    }
}]

NSLog(@"Your variable value : %@",yourVariable);
Raj Tandel
  • 359
  • 2
  • 12
3

You will need to pass in a call back/block of code to call out to.

- (void)someMethod
{
    [self enumerateWithCompletion:^(NSObject *aObject) {
        // Do something with result
    }];       
}

- (void)enumerateWithCompletion:(void (^)(NSObject *aObject))completion
{

[anNSMutableOrderedSet enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
    if ([(SomeClass*)obj isWhatIWant]) {
        *stop = YES;
        if (completion) {
            completion(obj);
        }
    }
}];
}

You could also use delegation, and call back to a delegate you have defined to return the object.

[self.delegate enumerationResultObject:obj];

UPDATE:

Realised enumerateObjectsUsingBlock: is actually called synchronously, so the better approach would be to use a __block variable. Callback would still work but could be construed as misleading.

Tim
  • 8,932
  • 4
  • 43
  • 64
  • Would it also be possible to use `__block SomeClass *someClassVar` outside the block, and then inside the block, do `someClassVar = obj` to assign the resulting object to the block variable located outside the block? I haven't tried it yet, but if I'm understanding the __block keyword correctly, it seems that would work – Logicsaurus Rex Mar 30 '16 at 11:19
  • @Logicsaurus Rex yes this will work. for more info about __block keyword check this link : http://stackoverflow.com/questions/7080927/what-does-the-block-keyword-mean – Raj Tandel Mar 30 '16 at 11:34
  • Yeah a block variable would also work. But be aware of scope when using this approach. I find using an explicit callback more readable but it is up to you and how it applies to your implementation. Good luck. – Tim Mar 30 '16 at 13:33
  • @Jeff Did you mean to enclose the enumeration code chunk inside the callback method. Won't that cause an infinite loop? – Logicsaurus Rex Mar 30 '16 at 17:52
  • I didn't define a callback, I'll edit my answer for clarity with a callback. – Tim Mar 30 '16 at 20:28
  • You shouldn't use completion handlers when it's always called synchronously, like here. – newacct Apr 05 '16 at 02:42
  • Valid observation - didn't realise this method was called synchronously. Made an update. – Tim Apr 05 '16 at 07:58
1

In this case, the easiest thing would be to not use enumerateObjectsUsingBlock:, and just use fast enumeration instead:

for (SomeClass *obj in anNSMutableOrderedSet) {
    if ([obj isWhatIWant]) {
        yourVariable = obj;
        break;
    }
}
newacct
  • 119,665
  • 29
  • 163
  • 224
-1

Try With Weak Self

    __weak SomeClass *weakSelf = self;
    [anNSMutableOrderedSet enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        if ([(SomeClass*)obj isWhatIWant]) {
            weakSelf = (SomeClass*)obj;
            *stop = YES;
            // Ok, found what I'm looking for, but how do I get it out to the rest of the code?
        }
    }];

//you Have to use weakSelf outside the block
Vvk
  • 4,031
  • 29
  • 51
  • This makes no sense and is a terrible idea. You are mixing up the type of `self` and the type of the objects in `anNSMutableOrderedSet`. In most cases those types will not be the same. – Kurt Revis Apr 05 '16 at 04:50