- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我需要一种方法来在运行时检查给定 block 的参数数量和参数类型(我目前正在编写的某些对象映射库需要这个,我正在将字符串格式的值映射到选择器,想要相同的 block )。
我尝试了以下示例中的代码,但出于某种原因它对我不起作用,并为字符串描述返回 nil。
您是否知道一种在运行时评估 block 签名的方法(最好是对 iPhone 应用商店提交的安全)?
这是我使用的代码:
struct BlockDescriptor {
unsigned long reserved;
unsigned long size;
void *rest[1];
};
struct Block {
void *isa;
int flags;
int reserved;
void (*invoke)(struct __block_literal_1 *);
struct BlockDescriptor *descriptor;
};
enum {
BLOCK_HAS_COPY_DISPOSE = (1 << 25),
BLOCK_HAS_CTOR = (1 << 26), // helpers have C++ code
BLOCK_IS_GLOBAL = (1 << 28),
BLOCK_HAS_STRET = (1 << 29), // IFF BLOCK_HAS_SIGNATURE
BLOCK_HAS_SIGNATURE = (1 << 30),
};
static const char *BlockSig(id blockObj)
{
struct Block *block = (void *)blockObj;
struct BlockDescriptor *descriptor = block->descriptor;
assert(block->flags & BLOCK_HAS_SIGNATURE);
int index = 0;
if(block->flags & BLOCK_HAS_COPY_DISPOSE)
index += 2;
return descriptor->rest[index];
}
-(NSString*)signatureForBlock:(id)block {
NSString* sig = [NSString stringWithUTF8String:BlockSig(block)];
sig = [sig substringFromIndex:1]; // remove c
NSArray* components = [sig componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"0123456789?"]];
sig = [components componentsJoinedByString:@""];
return sig;
}
然后做:
NSString * (^block)(int, NSArray *) = ^NSString * (int i, NSArray * a){
return @"Oh, yeah!";
};
NSLog(@"signature %s", BlockSig(block)); // ==> this returns null
来源: Checking Objective-C block type? https://github.com/mikeash/MABlockForwarding/blob/master/main.m
最佳答案
使用 CTBlockDescription ,您可以获得所需的所有运行时信息作为 NSMethodSignature
目的。用法很简单:
NSString * (^block)(int, NSArray *) = ^NSString * (int i, NSArray * a){
return @"Oh, yeah!";
};
NSMethodSignature *signature = [[[CTBlockDescription alloc] initWithBlock:block] blockSignature];
NSLog(@"signature %@", [signature debugDescription]);
这将输出以下签名:
signature <NSMethodSignature: 0x6844900>
number of arguments = 3
frame size = 12
is special struct return? NO
return value: -------- -------- -------- --------
type encoding (@) '@'
flags {isObject}
modifiers {}
frame {offset = 0, offset adjust = 0, size = 4, size adjust = 0}
memory {offset = 0, size = 4}
argument 0: -------- -------- -------- --------
type encoding (@) '@?'
flags {isObject}
modifiers {}
frame {offset = 0, offset adjust = 0, size = 4, size adjust = 0}
memory {offset = 0, size = 4}
argument 1: -------- -------- -------- --------
type encoding (i) 'i'
flags {isSigned}
modifiers {}
frame {offset = 4, offset adjust = 0, size = 4, size adjust = 0}
memory {offset = 0, size = 4}
argument 2: -------- -------- -------- --------
type encoding (@) '@'
flags {isObject}
modifiers {}
frame {offset = 8, offset adjust = 0, size = 4, size adjust = 0}
memory {offset = 0, size = 4}
关于NSBlock 的 iOS NSMethodSignature(或编码),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12715586/
我最近开始为 IOS 开发并与调用对象作斗争。 我有一个类“Location”,派生自 NSManagedObject(它是 Coredata 模型的一部分) @interface Location
在 ObjC 中我有: NSMethodSignature *ms = [[object.target class] instanceMethodSignatureForSelector:object
我正在使用此方法将方法分派(dispatch)给委托(delegate),不幸的是,我发现大多数时候 NSMethodSignature 为 nil,这是因为选择器来自协议(protocol)。我想知
我需要一种方法来在运行时检查给定 block 的参数数量和参数类型(我目前正在编写的某些对象映射库需要这个,我正在将字符串格式的值映射到选择器,想要相同的 block )。 我尝试了以下示例中的代码,
我在使用 [NSMethodSignature getArgumentTypeAtIndex] 函数时遇到了非常奇怪的行为。它返回 BOOL 类型的“@”字符,根据 objective-c type
我正在尝试在协议(protocol)方法中获取 block 的签名。 这是一个示例协议(protocol): @protocol ProtocolSample - (void) doSomethin
我如何在 swift 2 中编写这个类? NSMethodSignature 和 NSInvocation 在 swift 2 中不再存在 @implementation MyAuth - (void
在苹果的 documentation这个方法的最后说了以下内容: 特殊注意事项 此方法自 Mac OS X v10.0 起可用,在 Mac OS X v10.5 中公开。仅支持应用程序运行所针对的运行
我在手机上运行以下代码,其中“对象”是猫,它是动物的子类。动物有一个属性“颜色”: NSLog(@"Object: %@", object); NSLog(@"Color: %@", [object
我是一名优秀的程序员,十分优秀!