What is the correct syntax - ios

I want to define a block similar to NSArray enumerateObjects:usingBlock
my block is as follows
typedef void (^MyBlock)(BOOL *);
and i want to invoke it in some method, so that the method would give me the BOOL value to stop
how do I continue from here ?
EDIT:
I want to do the following
BOOL replaceSomething;
[self someMethod:MyBlock(&replaceSomething)] <== this syntax is not correct
if(replaceSomething){
do something
}
-(void)someMethod:^void(BOOL *stop){
*stop = YES;
}

Here's a handy and an easy to remember site when dealing with blocks:
http://fuckingblocksyntax.com
What you're looking for exactly is the last part (using typedef):
typedef void (^ MyBlock)(id, BOOL);
MyBlock myBlock = ^(id myId, BOOL myBool) {...};
P.S. Note that BOOL is not an object, but a primitive type.

Related

Using SNMP++ method with callback in .mm file

I am using SNMP++ library in my project and everything works fine. However, there is a method where I need to get callback in my .mm file. Now when I am creating a block and passing it to that function as parameter, it throws an error "No matching member function for call to 'get_bulk'". Here is the piece of code:
void(^callbackFunc)(int,Snmp*,Pdu&,SnmpTarget&,void*);
callbackFunc = ^(int i,Snmp* s,Pdu& p,SnmpTarget& t,void* v) {
};
snmp.get_bulk(pdu, *target, l_repeaters, l_repetitions,callbackFunc);
Also, here is the function signature for "get_bulk" function:
int Snmp::get_bulk(Pdu &pdu, // pdu to use
const SnmpTarget &target, // destination target
const int non_repeaters, // number of non repeaters
const int max_reps, // maximum number of repetitions
const snmp_callback callback,// callback to use
const void * callback_data) // callback data
{
pdu.set_type( sNMP_PDU_GETBULK_ASYNC);
return snmp_engine( pdu, non_repeaters, max_reps, target,
callback, callback_data);
}
What should I pass in 'callback' type?This is the typedef for SNMP_callback:
typedef void (*snmp_callback)(int reason, Snmp *session,
Pdu &pdu, SnmpTarget &target, void *data);
I am stuck on this for the past 4-5 hours now and I can't figure out how to resolve this.
Apple's blocks are not convertible to function pointers, as they also contain data (captured variables, etc.) and a reference counting mechanism. You will need to pass a free function, static C++ class member function, or a C++ non-capturing lambda as the callback.
The lambda is the closest syntactically to a block; only non-capturing lambdas are convertible to a function pointer, however, so you will need to do the capturing "by hand" by passing a pointer to a context struct or similar through the void* callback_data argument which presumably is passed through to the callback as void* data.
The lambda will look something like this:
snmp_callback callback =
[](int reason, Snmp *session, Pdu &pdu, SnmpTarget &target, void *data)
{
// context_struct_type* context = static_cast<context_struct_type*>(data);
};

How to define a function in objective c

I want to translate this code from Swift to Objective C:
typealias Completion = ([Media]?) -> Void
I have look over Stack Overflow posts, but I don't see the answer for this.
typedef void (^CompletionBlock) ( NSArray<Medial*>* _Nullable array);
typedef void (^CompletionBlock) (NSArray* array);

How to check whether a protocol contains certain method programatically in Objective-C?

Is there any way to check whether a protocol contains certain method or whether a method belongs to certain protocol in Objective-C?
I don't think the redirected question is the same as mine. What I want is:
[MyProtocol containsSelector:#selector(MySelector)];
Or
[MySelector isMethodOfProtocol:#protocol(MyProtocol)];
See the Objective-C runtime functions
Protocol *objc_getProtocol(const char *name)
struct objc_method_description *protocol_copyMethodDescriptionList(Protocol *p, BOOL isRequiredMethod, BOOL isInstanceMethod, unsigned int *outCount)
The documentation can, at the time of this writing, be found here.
If you know the name of the method, here is what you can do :
First set the delegate of the protocol.
Then, check if the method belongs to the protocol as this :
if ([something.delegate respondsToSelector:#selector(someMethodToCheck)])
Here is a small code snippet I am using right now (thanks to Avi's answer above):
- (BOOL)isSelector:(SEL)selector
ofProtocol:(Protocol *)protocol {
unsigned int outCount = 0;
struct objc_method_description *descriptions
= protocol_copyMethodDescriptionList(protocol,
YES,
YES,
&outCount);
for (unsigned int i = 0; i < outCount; ++i) {
if (descriptions[i].name == selector) {
free(descriptions);
return YES;
}
}
free(descriptions);
return NO;
}
You can move this to a category on NSObject too, if you use forwarding extensively.
Here is a function I found Apple using:
#import <objc/runtime.h>
BOOL MHFProtocolHasInstanceMethod(Protocol *protocol, SEL selector) {
struct objc_method_description desc;
desc = protocol_getMethodDescription(protocol, selector, NO, YES);
if(desc.name){
return YES;
}
desc = protocol_getMethodDescription(protocol, selector, YES, YES);
if(desc.name){
return YES;
}
return NO;
}
Use like this:
- (id)forwardingTargetForSelector:(SEL)aSelector{
if(MHFProtocolHasInstanceMethod(#protocol(UITableViewDelegate), aSelector)){
...

Blocks with no return value

Is there a proper way to write a block with no return value in Objective-C? All the examples that I have seen are all with return values. Can someone also please explain the difference between a completion block & a regular block? I know the ^ means that it is a block but doesn't the + before (void) mean it is a block as well?
Here is what a method header would look like if it has a parameter of a block:
- (void)someMethodThatTakesABlock:(returnType (^)(parameterTypes))blockName;
So a block with no return type and no parameters would look something like this:
- (void)someMethodThatTakesABlock:(void (^)(void))blockName;
A regular block is just a set (or group) of code. A completion block is a block that will be executed when the method is completed. A completion block is a regular block, it just is specific to being called at the end of a method.
The ^ signifies a block. The + before a method is a class method.
Other ways to use blocks
As a local variable
returnType (^blockName)(parameterTypes) = ^returnType(parameters) {...};
As a property
#property (nonatomic, copy) returnType (^blockName)(parameterTypes);
As a method parameter
- (void)someMethodThatTakesABlock:(returnType (^)(parameterTypes))blockName;
As an argument to a method call
[someObject someMethodThatTakesABlock:^returnType (parameters) {...}];
As a typedef
typedef returnType (^TypeName)(parameterTypes);
TypeName blockName = ^returnType(parameters) {...};
You would just replace returnType with void.
Here is a demo:
1、no return values and no parameter:
- (void)viewDidLoad {
[super viewDidLoad];
//block
void(^myBlock)(void) = ^(void) {
NSLog(#"This is a block without parameter and returned value");
};
myBlock();
2、no return values and have parameter:
-(void)blockWithParameterButNoReturnData
{
void(^myBlock)(int) = ^(int num) {
NSLog(#"%d",num*100);
};
myBlock(4);
}
3、have retrun values and have parameter:
-(void)blockWithParameterAndReturnValue
{
int (^myBlock)(int) = ^(int num) {
return num * 100;
};
int result = myBlock(2);
NSLog(#"This is a block with parameter and return value :%d",result);
}
PS:for more infomation,see this website:http://www.cnblogs.com/zhanggui/p/4656440.html

Return the result of the outer method from the block in Objective-C

I have a method that creates a block inside. Is it possible to return the result of the method from this block? Something like:
- (id)myFunction {
//some code here
BlockType myBlock = ^{
//some other code here
return someObject; //is it possible to return something for myFunction?
};
[someOtherObject methodWithBlock: myBlock];
}
Blocks can have a return type. Here's an example.
First you define a block type (optional, but convenient)
typedef NSString * (^BlockType)(NSString *name);
^^^^^^^^^^ ^^^^^^^^^ ^^^^^^^^^^^^^^
return type type name parameters
Then you can instantiate a block like follows
BlockType aBlock = ^ NSString * (NSString *name){
return [#"Hello " stringByAppendingString:name];
};
And use it
NSString *salutation = aBlock(#"Nikita");
NSLog(#"%#", salutation); // => Hello Nikita

Resources