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

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

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.

What is the use of storing the block in an instance variable
Perhaps to be able to access it later?

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).

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!

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");
}

Related

How to return multiple results from Asynchronous method?

Note: This question doesn't have anything to do with the language used, i.e, Swift/ Objective-C
I can't seem to get my head around how such a problem can be solved.
How an asynchronous method which processes data continuously ,return back these processed values to a function?
Example Class structure of -> ClassName
A method named -(void)infoCallBack , this is the method you have to call to get returns continuously.
Inside -(void)infoCallBack -> an asynchronous method [self startRecording]is there, which does audio recording asynchronously using AudioQueues by using a callback method void AudioInputCallback(..param..).
Finally Inside void AudioInputCallback(..param..) -> a method -(void) processAudio is there, which continuously processes data and gives us an integer number.
How to call a method like [ClassName infoCallBack] in such a way that we keep getting all these processed integers continuously?
Edit : I have searched SO, and came across completion handler blocks : although completion handlers only return a value once after completionHandler() is called. Moreover, another problem in this method was how to pass around this completionHandler to multiple methods in the className Structure as shown.
I came across delegates, it said that when distinct values are being returned continuously and state of something changes, then we should call a delegate. But I was stuck at how I would return values after I call the function infoCallBack from ClassName, i.e, [ClassName infoCallBack] which continuously can feed the person calling this function with the values being processed.
Actually I don't completely understand your question but I will give you the answer in my understanding
In my opinion, you can use block to handle process update.
typedef void (^ProcessHandlerBlock) (NSInteger i);
- (void)infoCallBackWithProcessHandlerBlock:(ProcessHandlerBlock)block {
[self startRecordingWithProcessHandlerBlock:(ProcessHandlerBlock)block];
}
- (void)startRecordingWithProcessHandlerBlock:(ProcessHandlerBlock)block {
[self audioInputCallbackWithParam1:#"1" param2:#"2" processHandlerBlock:(ProcessHandlerBlock)block];
}
- (void)audioInputCallbackWithParam1:(id)param1 param2:(id)param2 processHandlerBlock:(ProcessHandlerBlock)block {
[self processAudioWithProcessHandlerBlock:(ProcessHandlerBlock)block];
}
- (void)processAudioWithProcessHandlerBlock:(ProcessHandlerBlock)block {
// Assume this is your process method callback
[NSTimer scheduledTimerWithTimeInterval:1.f repeats:YES block:^(NSTimer * _Nonnull timer) {
// After receive integer, pass it to block.
block(1);
}];
}
When you want to use them, call
[self infoCallBackWithProcessHandlerBlock:^(NSInteger i) {
NSLog(#"%l", i); // Do whatever you want here
}];
Inside the completion block of infoCallBackWithProcessHandlerBlock method, you can use result integer to do what you want.
I can't seem to get my head around how such a problem can be solved.
From the rest of what you've written I suspect you can get your head around this, you probably just need a rest. You've found the answer already without realising...
I have searched SO, and came across completion handler blocks : although completion handlers only return a value once after completionHandler() is called.
The phrase "completion handler block" might be written as "a block used as a completion handler" - a block is just a block, you can call it as many times as needed, store it in variables, etc. While a completion handler is typically only called once a, say, result reporter might be called multiple times.
Moreover, another problem in this method was how to pass around this completionHandler to multiple methods in the className Structure as shown.
A block is a kind of object and like other objects your class instance might need to use in many methods it doesn't need to be passed around but can be stored in an instance variable. For ease of use first declare your a shorthand for the block type, say:
typedef void (^SampleHandler)(int i);
then declare a suitable instance variable:
#implementation ClassName
{
SampleHandler mySampleHandler;
}
now use this like any other instance variable - initialise it (mySampleHandler = ...;), use it to call the block (mySampleHandler(42);`)
I came across delegates, it said that when distinct values are being returned continuously and state of something changes, then we should call a delegate. But I was stuck at how...
Blocks and delegates are often used for similar purposes, you can use either to solve your problem in essentially the same way - store the block/delegate reference in an instance variable, call the block/delegate method to return a value. You just have to decide which suits your use case best:
A block is a function. A block is created inline, usually at the call site, and can reference (and sometimes modify) variables in the environment where it is created. Like any function it is (usually) a single-operation thing - pass argument(s), produce a side-effect/return a result.
A delegate is an object. Like any other object it requires an interface/implementation. Like any object it can have multiple methods, so its a multi-operation thing.
In your case - returning a value - a block is probably the best option, but you need to decide.
HTH

Can I implement a property setter in such a way that it calls another method generically to perform the set?

Consider the below setters:
- (void)setWinterStatus:(NSString *)status
{
NSLog(#"Variable update called");
if (_status != status)
{
[_status release];
_status = [status retain];
NSLog(#"Variable actually updated");
}
}
- (void)setCharacterState:(EnumCharacterState)state
{
NSLog(#"Variable update called");
if (_state != state)
{
_state = state;
NSLog(#"Variable actually updated");
}
}
Notice the methods are similar - it logs a generic message, checks if it's actually changing, effects the change, and logs if it does so. If I had enough such methods, I might want to write a wrapper, so that I could simply write:
- (void)setCharacterState:(EnumCharacterState)state
{
[setValue:#(state) forSelector:#selector(state)];
}
But I'm not sure if this is possible. I can't use KVO as it seems the KVO code added by default actually call's the setter, so doing so results in endless recursion. I don't know how to get the instance variable from #selector(state), nor check whether it needs release/retain. Any way to do this?
One note: the object type's base class has to remain NSObject; I can't use NSManagedObject as a base and handle my own KVO.
Edit:
So there apparently is a way using the runtime c functions (see accepted answer); seems like it could take some time to get right, but I found another solution in the interim. I register myself an an observer for all the methods I want to 'wrap', observing NSKeyValueObservingOptionNew, NSKeyValueObservingOptionOld, and NSKeyValueObservingOptionPrior. Then in the prior handler, I NSLog(#"Variable update called"), and in the update handler, I NSLog(#"Variable actually updated"). This seems to be working out well :)
Short Answer: Yes, but don't.
Long Answer:
Assuming you want to do this for educational reasons (rather than just have the compiler create the setter for you, the default in recent compilers) it is possible, but it is non-trivial.
You've noticed one difference - whether you need to retain/release (assuming MRC) - but there are more. For example, consider the simple line:
_state = state;
What does it do? Copy a byte? Two bytes? Eight bytes? The code might look the same in different setters but it compiles to different machine code.
And then there are copy and weak attributes on properties to consider...
Still considering doing this?
You'll need to be comfortable with what void ** means, copying data of variable length via pointers, etc. Then take a look at object_setInstanceVariable, property_getAttributes etc. - these are all C functions, you'll find them in Objective-C Runtime Reference.
From that you'll find you need to know about type encodings (which will help you with how many bytes to copy around), and more...
Have fun!
HTH

Closures in Swift, blocks in Objective-C: their usefulness and when to use

I've found an Objective-C SocketIO library and am trying to implement it in my first Swift app. Here's the code I'm trying to port:
__weak typeof(self) weakSelf = self;
self.socket.onConnect = ^()
{
weakSelf.socketIsConnected = YES;
[weakSelf mapView: weakSelf.mapView didUpdateUserLocation: weakSelf.mapView.userLocation];
};
From my limited understanding ^() {} is a block in Objective C. I've looked into it and closures seem to be a loose equivalent Swift. My first obvious question is how do I get the same result in Swift?
I've tried the following but get the error fatal error: unexpectedly found nil while unwrapping an Optional value (lldb):
self.socket.onConnect = { () -> Void in
println("Connected!")
}
Also, behind the scenes what's happening here? An asynchronous callback function would seem appropriate but wasn't used and I'd like to understand why.
UPDATE
As pointed out by #jtbandes, socket was in fact Nil as this code was running outside of the connection callback (I know, a very silly mistake). Solution to first question:
SIOSocket.socketWithHost(server) { (socket: SIOSocket!) in
self.socket = socket
self.socket.onConnect = { () -> Void in
println("Connected!")
}
}
Objective-C blocks and Swift closures are more than loose equivalents. They are direct equivalents.
A block/closure is an anonymous function that inherits it's enclosing scope.
I'm still working in Objective-C, so I'm used to its terminology. I'll use those terms
Blocks are useful in lots of ways.
Completion code is one example.
Without blocks, if you're setting up an async networking class, you might give it a delegate property, and define a protocol with callbacks that the class uses to notify it's delegate about events like download complete, errors, etc.
This makes for a lot of message handling infrastructure in lots of different places. You have to define a protocol. You have to add a delegate property to the networking class. You have to implement a set of delegate messages in the client class. You may have to pass context information to the callbacks, etc.
With blocks, you invoke a method that asks for a networking service, and provide a completion block. When the service is complete, it invokes the provided code block. You might add parameters to the completion block like a pointer to the data, a success boolean, or whatever is appropriate. The code block can have access to all the variables defined in its enclosing scope, which can be very helpful.
You can also save blocks into collections, you can use blocks in sort methods, and int lots of other cases.
The code you posted simply sets a block property on the object in question, self.socket. It looks like it is a block of code that gets called after a socket connection is established.
There are direct equivalents to this in Swift. I've only poked around in Swift however, so I'll leave it to others to help you with the translation.
I suggest browsing through Apple's classes for ideas on how to use blocks. Take a look at NSURLConnection and NSURLSession if you're interested in async networking. Take a look at the block-based view animation methods that take an animation block and a completion block. Those will give you an idea of the ways you can use blocks for handling async events, or passing code to a class to get work done.
Another interesting use of blocks is in handling collections like arrays. There are methods that take an NSComparator block and sort an array, and there are methods that will enumerate through an array, performing a block of code on each element and/or selecting a subset of the elements and returning an index set of the array indexes.
Duncan

Is there a good way to prevent recursion of a particular bit of code in Objective-C?

Here is what I'm currently doing for a looping scroll-view:
// Call the on-scroll block
static BOOL inOnScrollBlock = NO;
if((_onScrollBlock != nil) && !inOnScrollBlock)
{
inOnScrollBlock = YES;
_onScrollBlock(self, self.loopOffset);
inOnScrollBlock = NO;
}
This is in the setContentOffset for the looping scroll view. So the user can run code whenever it scrolls. If you set up two of these and you want them to track each other, so for both you supply a block that sets the other then you can get a recursive situation where they keep calling each other.
Actually in this case it's not too bad as there's a separate check to see if the value being set is already set before doing all the more advanced stuff, but because it's a looping view there are multiple equivalent values so it can happen a few times.
Anyway, the question is about preventing recursion in this kind of situation. Given that this is a UI method and therefore only called on the main thread, is my approach of a simple flag to catch when you're being called from within the block a reasonable one, or not?
Are there any language features or framework patterns (available in iOS) to do this - similar to #synchronized or dispatch_once but to prevent recursion of a particular code section?
I wouldn't use a static BOOL as a static is implemented at class level. What if you had two instances of this class? They would be shooting each other in the foot! At the very least, use an instance variable (i.e. a property, and don't declare it nonatomic either, just in case).

Blocks vs private methods?

What are the disadvantages of using a block to define a private method within a method, instead of using a real private method? Is there any apart from not being able to call the method from somewhere else?
Example:
-(NSDictionary*)serialize
{
NSMutableDictionary* serialization = [NSMutableDictionary dictionary];
TwoArgumentsBlockType serializeItemBlock = ^void(MyItemClass* item, NSString* identifier)
{
if (item)
{
// serialization code
}
};
serializeItemBlock(self.someItem1, kSomeIdentifier1);
serializeItemBlock(self.someItem2, kSomeIdentifier2);
serializeItemBlock(self.someItem3, kSomeIdentifier3);
serializeItemBlock(self.someItem4, kSomeIdentifier4);
serializeItemBlock(self.someItem5, kSomeIdentifier5);
serializeItemBlock(self.someItem6, kSomeIdentifier6);
serializeItemBlock(self.someItem7, kSomeIdentifier7);
serializeItemBlock(self.someItem8, kSomeIdentifier8);
serializeItemBlock(self.someItem9, kSomeIdentifier9);
serializeItemBlock(self.someItem10, kSomeIdentifier10);
serializeItemBlock(self.someItem11, kSomeIdentifier11);
return serialization;
}
I think the 3 biggest drawbacks are:
The block isn't reusable, as you mention.
The block isn't testable--you can't write a unit test that verifies the block does what you think it does.
The code is less readable. When you're reading this method, what's important is that a series of things are serialized, not the details of how the serialization is implemented.
Moving this block into a method would resolve all of these issues. If the block is used by some API that takes a block callback as an argument, you can always return the block from a method.
Clarity of the code is important.
Methods allow you to encapsulate entire sections of code apart from each other, and can make it easier to read..
Another reason to choose private methods over blocks is memory management. This is far to big of a topic to discuss here, but sufficed to say that blocks are weird in the memory management, and don't act like any other code structure in that regard.
Arguably it's harder to navigate the code - you tend to have entry points buried rather obscurely in the middle of some function, and there's no function name you can see in the debugger or search for, which can make debugging and tracing a little harder.

Resources