Raj
Raj

Reputation: 1139

What is the use of storing the block in an instance variable

I am aware that blocks are one of the latest feature added in ios. But I am really finding a

tough time learning it .

I have seen people doing the following

typedef void(^CallBackBlk) (NSString *);


@property(copy,nonatomic)CallBackBlk block;

and in .m class

-(void)doSomething:(CallBackBlk )cb{

       self.block=cb;

}

I never understood what is the use of assigning it to cb here. Can't I simply do the following

-(void)doSomthing{

   block(@"my string");

}

I am really not getting the purpose of storing the block in instance variable. Can any help

me with an example. Any help is greatly appreciated

Upvotes: 1

Views: 143

Answers (5)

bbum
bbum

Reputation: 162712

In your doSomething method, where does block come from?

Answer that, and you'll have your reason.


Ah -- the commentary makes the question clear. Snark served a purpose (snark and too lazy to type out a real answer on my iPhone at 7AM :).

An instance variable is just a slot to put things. Nothing is in that slot to start with.

In your case, you could implement:

-(void)doSomething:(CallBackBlk )cb{
       cb();    
}

However, typically, a callback is used when you do something asynchronously. For example, you might do:

[myObject doSomething:^{
     NSLog(@"did something");
 }];

And then:

-(void)doSomething:(CallBackBlk)cb {
    dispatch_async(... global concurrent queue ..., ^{
         ... do some work ...
         cb();
    });
 }

That is, doSomething: will return as soon as the dispatch_async() happens. The callback block is used to callback to let you know that asynchronous operation is done.

Of course, still no need for an instance variable. Take that class that does something a bit further; make it some kind of relatively complex, state transitioning, engine. Say, like your average internet downloader or compute heavy simulation engine. At that point, lumping all your background work into a single method would be overly complex and, thus, shoving the callback block(s) (there may likely be more than one; a progress updater, a completion block and/or an error block, for example) into instance variables allow the class's implementation to be subdivided along lines of functionality more cleanly.

Upvotes: 4

jszumski
jszumski

Reputation: 7416

To use the block, you call your doSomething: method:

CallBackBlk laterBlock = ^(NSString *someString) {
    NSLog(@"This code is called by SomeClass at some future time with the string %@", someString);
};

SomeClass *instance = [[SomeClass alloc] init];
[instance doSomething:laterBlock];

As you code the implementation of your class, it will presumably reach some condition or finish an action, and then call the laterBlock:

if (someCondition == YES) {
    self.block("Condition is true");
}

Upvotes: 0

Fonix
Fonix

Reputation: 11597

maybe and example of use will help..

one use for storing it as a variable i have found is if you have multiple views that all access another view (for me it was a map on the next view) i used blocks that were setup by the previous view (set the default location for the map, initialise markers and so forth) then passed it through to the next view, where it would run it, setting up the map. it was handy having the block use the local variables of the previous view to access certain attributes. it wasnt the only way to do it, but i found it was a nice clean way of going about it.

and here is an example of what gets run in the viewDidLoad of the mapview

if(setupMap){
    setupMap(mapView);
}

if(gpsUpdate){
    gpsUpdate(mapView);
}

if(addMarker){
    addMarker(mapView);
}

now if those blocks were assigned (the if statement check if they are nil), it would run them and do the appropriate setup for the map. not every view needed to do those, so they would only pass to the map view what needed to be done. this keeps the map view very general purpose, and code gets reused a lot. write once use lots!

Upvotes: 0

omz
omz

Reputation: 53551

You would do that if you want to invoke the block later, after the method that assigns it has already returned.

Consider for example an object that manages a download. You might want to have a block that gets invoked when the download completes (e.g. to update the UI), but you don't want the download method to have to wait until that happens (because it might take a long time).

Upvotes: 1

user529758
user529758

Reputation:

What is the use of storing the block in an instance variable

Perhaps to be able to access it later?

Upvotes: 1

Related Questions