0

I'm using blocks to update my collection view when results are coming back. But i only want to block to be executed if shouldLoadMoreResults is YES

I am changing him from another method to NO but no matter what he is always on YES.

I'm assuming that the block captures the state, what am i doing wrong ?

-(void) getMoreResults
{   self.shouldLoadMoreResults = YES;




        [searchRequest startSearchWithComplition:^{
            if (self.shouldLoadMoreResults)
            {
                ...
            }
rmaddy
  • 314,917
  • 42
  • 532
  • 579
Or Ron
  • 2,313
  • 20
  • 34
  • I hope you're doing "`startSearchWithCompletion:`" and not "`startSearchWithComplition:`"... – Michael Dautermann Apr 06 '14 at 08:22
  • The block is probably being executed before you change the value, it doesn't save the state of instance variables. – pNre Apr 06 '14 at 08:22
  • The block captures `self` but not the value of the property `shouldLoadMoreResults`. If you execute `self.shouldLoadMoreResults` which is actually sending self a message, it would return the current value of the property, including the effects of potential data races (when you change the value from different threads concurrently). – CouchDeveloper Apr 06 '14 at 08:33
  • @CouchDeveloper i have a breakpoint where i change it to no and its happening before the block for sure – Or Ron Apr 06 '14 at 08:38
  • @pNre see my last comment – Or Ron Apr 06 '14 at 08:47
  • Could you show me more source code? – Kyokook Hwang Apr 06 '14 at 09:06
  • @race_car's answer below looks promising. What we do know is that the block isn't "capturing" a BOOL's value. The BOOL is getting changed by the code in a way that's somehow unexpected. Please place an NSLog next to _every_ touch of that property. Log the line number where the log statement is, so you know who the culprit is. You'll find it. – danh Apr 06 '14 at 18:47

2 Answers2

1

I think you made a simple mistake. If self.shouldLoadMoreResults = YES; is executed every time -getMoreResults is called then isn't it pretty likely that if (self.shouldLoadMoreResults) is going to evaluate to YES every time?

race_carr
  • 1,387
  • 12
  • 21
  • I actually wrote in the question that I'm changing the value before the block is executed – Or Ron Apr 10 '14 at 07:43
  • You might need to use __block to allow shared storage with `shouldLoadMoreResults`. However then you run into problem with [retain cycles when capturing self](http://stackoverflow.com/questions/7853915/how-do-i-avoid-capturing-self-in-blocks-when-implementing-an-api?rq=1). – race_carr Apr 11 '14 at 16:16
0

In order to clear a few things up, here is a small program which simulates the issue, and its result. Basically, it shows the OPs issue is somewhere else, and the code should work as expected.

#import <Foundation/Foundation.h>

@interface Foo : NSObject
@property (nonatomic, assign) BOOL flag;
@end

@implementation Foo
@synthesize flag = _flag;
@end


int main(int argc, const char * argv[])
{
    @autoreleasepool {

        Foo* foo = [[Foo alloc] init];

        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            foo.flag = YES;
        });

        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            NSLog(@"flag: %@", foo.flag ? @"YES" : @"NO");
        });
    }
    [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];

    return 0;
}

The output is:

2014-04-06 11:05:08.007 Test[6825:303] flag: YES

CouchDeveloper
  • 18,174
  • 3
  • 45
  • 67