标签: objective-c-runtime

Objective-C中的class_addMethod只能在特定实例上工作吗?

我正在尝试编写一些动态代码,用户可以尝试从类的特定实例调用方法,并在运行时解析它.检索信息的实现存在,但访问它的方法不存在,因为它基于每个实例.

例如,用户可能想要调用类中不存在的名为"getSomething"的方法:

[someInstance getSomething]
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我希望有一个实现已解析,它具有一个仅适用于正在处理的实例的变量返回类型.我正在考虑使用Objective-C中的class_addMethod,但我并不是100%肯定它的行为.在文档中,它声称这可以用于添加类或实例方法.调用此类是否仅将方法添加到特定实例或类中,以便之后创建的每个实例都将具有该方法?我还读到,一旦添加了一个方法,你就无法删除它.

也许我的方法不正确,所以如果知道任何替代方案我会很感激.我不能使用消息转发,因为没有类可以理解已经实现的选择器.

dynamic objective-c objective-c-runtime resolve

8
推荐指数
2
解决办法
5532
查看次数

获取类方法列表

我正在寻找一种方法来获取某个类的静态方法列表.我只获得了运行时函数的实例方法列表class_copyMethodList().

有没有办法列出静态方法?

objective-c objective-c-runtime

8
推荐指数
1
解决办法
2709
查看次数

如何从ARC下的运行时定义的类方法返回结构值?

我有一个返回a的类方法CGSize,我想通过Objective-C运行时函数调用它,因为我将类和方法名称作为字符串值.

我正在使用XCode 4.2中的ARC标志进行编译.

方法签名:

+(CGSize)contentSize:(NSString *)text;
Run Code Online (Sandbox Code Playgroud)

我尝试的第一件事是用objc_msgSend这样调用它:

Class clazz = NSClassFromString(@"someClassName);
SEL method = NSSelectorFromString(@"contentSize:");

id result = objc_msgSend(clazz, method, text);
Run Code Online (Sandbox Code Playgroud)

这与"EXC_BAD_ACCESS"崩溃并且没有堆栈跟踪.我首先使用了这个,因为文档objc_msgSend说,

当遇到一个方法调用,编译器生成到的功能之一的呼叫objc_msgSend,objc_msgSend_stret,objc_msgSendSuper,或objc_msgSendSuper_stret.[...]使用objc_msgSendSuper_stret和发送具有数据结构作为返回值的方法objc_msgSend_stret.

接下来,我用objc_msgSend_stret这样的:

Class clazz = NSClassFromString(@"someClassName);
SEL method = NSSelectorFromString(@"contentSize:");

CGSize size = CGSizeMake(0, 0);
objc_msgSend_stret(&size, clazz, method, text);
Run Code Online (Sandbox Code Playgroud)

使用上面的签名给出了以下两个编译器错误和两个警告:

错误:自动引用计数问题:ARC不允许将非Objective-C指针类型'CGSize*'(又名'struct CGSize*')隐式转换为'id'

警告:语义问题:不兼容的指针类型将'CGSize*'(又名'struct CGSize*')传递给'id'类型的参数

错误:自动引用计数问题:ARC不允许将Objective-C指针隐式转换为"SEL"

警告:语义问题:不兼容的指针类型将'__unsafe_unretained Class'传递给'SEL'类型的参数

如果我查看方法的声明,它是:

OBJC_EXPORT void objc_msgSend_stret(id self, SEL op, ...)
    __OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
Run Code Online (Sandbox Code Playgroud)

这与 …

struct objective-c objective-c-runtime class-method automatic-ref-counting

8
推荐指数
2
解决办法
6410
查看次数

什么是`objc_msgSend_fixup`,究竟是什么?

我正在搞乱Objective-C运行时,尝试编译Objective-c代码而不将其链接起来libobjc,并且我对程序有一些分段错误问题,所以我从中生成了一个汇编文件.我认为没有必要显示整个程序集文件.在我的main功能的某些方面,我有以下一行(顺便说一句,这是我得到seg错误之后的行):

callq   *l_objc_msgSend_fixup_alloc
Run Code Online (Sandbox Code Playgroud)

这是以下定义l_objc_msgSend_fixup_alloc:

.hidden l_objc_msgSend_fixup_alloc # @"\01l_objc_msgSend_fixup_alloc"
    .type   l_objc_msgSend_fixup_alloc,@object
    .section    "__DATA, __objc_msgrefs, coalesced","aw",@progbits
    .weak   l_objc_msgSend_fixup_alloc
    .align  16
l_objc_msgSend_fixup_alloc:
    .quad   objc_msgSend_fixup
    .quad   L_OBJC_METH_VAR_NAME_
    .size   l_objc_msgSend_fixup_alloc, 16
Run Code Online (Sandbox Code Playgroud)

我重新实现objc_msgSend_fixup了一个函数(id objc_msgSend_fixup(id self, SEL op, ...))返回nil(只是为了看看会发生什么),但是这个函数甚至没有被调用(程序在调用之前崩溃).

所以,我的问题是,callq *l_objc_msgSend_fixup_alloc应该做什么以及objc_msgSend_fixup(之后l_objc_msgSend_fixup_alloc:)应该是什么(一个函数或一个对象)?

编辑

为了更好地解释,我没有将我的源文件与objc库链接.我想要做的是实现libray的一些部分,只是为了看它是如何工作的.这是我所做的一种方法:

#include <stdio.h>
#include <objc/runtime.h>

@interface MyClass {

}
+(id) alloc;
@end

@implementation MyClass
+(id) alloc {
  // alloc the object
  return nil;
}
@end

id objc_msgSend_fixup(id …
Run Code Online (Sandbox Code Playgroud)

assembly objective-c objective-c-runtime segmentation-fault

8
推荐指数
2
解决办法
999
查看次数

使用class_getInstanceMethod - 在类层次结构中实现的方法在哪里?

是否有可能在类层次结构中找到检索方法的class_getInstanceMethod来源?例如,假设A类实现了myMethod.现在说我已经在A1类中继承了A类.如果我打电话class_getInstanceMethod(ClassA1, myMethod),是否可以判断结果方法是否已在ClassA1中被覆盖或直接来自A1?

我想如果你有权访问ClassA和ClassA1,就可以比较IMP的内存地址,但是我没有直接访问A.

objective-c objective-c-runtime ios

8
推荐指数
1
解决办法
1817
查看次数

Objective-C运行时:声明类型为Class(objc_class)的变量符合协议意味着什么?

Class bah = [NSString class];

id object = [bah new];
Run Code Online (Sandbox Code Playgroud)

编译完全没有问题.

Class<NSSecureCoding> bah = [NSString class];

id object = [bah new];
Run Code Online (Sandbox Code Playgroud)

返回错误"选择器'new'没有已知的类方法".

为什么第一个实例理解它可以调用+newNSObject上定义的方法但第二个实例不能?

objective-c objective-c-runtime

8
推荐指数
1
解决办法
379
查看次数

为什么gcc或clang不能正确编码SIMD矢量类型?

在对矢量类型和ObjC运行时进行一些处理时,我遇到了一个非常令人困惑的问题.

就我所知,clang或GCC都不会为任何SIMD矢量类型提供"正确的"类型编码.

#import <Foundation/Foundation.h>

int main() {
    typedef int int4 __attribute__((vector_size(16)));
    typedef float float4 __attribute__((vector_size(16)));

    NSLog(@"Int4: %s", @encode(int4));
    NSLog(@"Float4: %s", @encode(float4));
}
Run Code Online (Sandbox Code Playgroud)

当使用GCC或clang编译和运行时,我得到以下输出:

2014-04-09 06:21:01.102 test[1707:507] Int4:
2014-04-09 06:21:01.103 test[1707:507] Float4:

而不是我期望的,这将是这样的:

2014-04-09 06:21:01.102 test[1707:507] Int4: ![16,16i]
2014-04-09 06:21:01.103 test[1707:507] Float4: ![16,16f]

根据此处的文档:

vectors'!['后跟vector_size(构成向量的字节数),后跟逗号,后跟向量的对齐(以字节为单位),后跟元素的类型,后跟']'

尝试从ObjC方法返回这些类型时会出现问题,而不是像![16,16i]@:以下方法的编码那样获得逻辑:

-(int4) foo;
Run Code Online (Sandbox Code Playgroud)

我只得到了这个字符串@:,这会导致他们两个NSMethodSignature并且NSInvocation基本上扯掉他们的裤子和段错误.

是否有一些编译器选项可以启用以恢复矢量类型的正确编码?或者这里唯一的解决方案是"不从ObjC方法返回向量"?

注意:返回(或传递)指向向量的指针也没有帮助,因为指向矢量的指针的编码很简单^,然后贪婪地匹配列表中的下一个参数,导致我的参数计数关闭再来一次.我想我可以将矢量转换为a void *,但那时真的是一个丑陋的黑客.

vector objective-c simd clang objective-c-runtime

8
推荐指数
1
解决办法
467
查看次数

为什么Objective C对象的isa字段与其类指针有1个偏移量?

我正在尝试使用以下代码来理解NSObject的C结构布局.首先,我使用NSData打印其结构布局,然后直接使用打印类指针[NSObject class].

id obj = [NSObject new];
long nsSize = class_getInstanceSize([NSObject class]);
NSData *nsData = [NSData dataWithBytes:(__bridge const void *)obj length:nsSize];
NSLog(@"obj: %@", nsData);
NSLog(@"NSObject Class: %p", [NSObject class]);
Run Code Online (Sandbox Code Playgroud)

我得到了结果:

2015-10-15 08:11:53.913 ObjC_CMD[11406:1999149] obj: <f1e06573 ffff1d00>
2015-10-15 08:11:53.913 ObjC_CMD[11406:1999149] NSObject Class: 0x7fff7365e0f0
Run Code Online (Sandbox Code Playgroud)

有趣的是类指针的结尾是e0f0,而NSData打印结果显示它的isa为eof1(由于小端,它的顺序相反).我在书中读到isa指针在对象的结构布局中是最顶层的,那么为什么它有1个偏移

顺便说一句,我也试过其他类型的对象,isa和类指针之间总有1个偏移量.它们不应该是一样的吗?

PS我刚注意到类指针以0x7fff开头,但C struct中的isa似乎是0xffff,这种差异也很有趣.isa字段和类指针之间的确切关系是[NSObject class]什么?

c struct pointers objective-c objective-c-runtime

8
推荐指数
1
解决办法
233
查看次数

方法不能标记为@objc,因为其结果类型无法在Objective-C中表示

我在Objective-C和Objective-C运行时暴露了swift API.

当我在函数抛出错误之前添加"@objc"时"无法将方法标记为@objc,因为其结果类型无法在Objective-C中表示"

我的代码在这里

@objc public static func logIn(_ userId: String) -> User? { }
Run Code Online (Sandbox Code Playgroud)

用户是可选的结构.怎么解决这个问题.

objective-c optional-parameters objective-c-runtime ios swift

8
推荐指数
2
解决办法
9250
查看次数

找出Objective-C类是否覆盖方法

如何在运行时找出类是否覆盖其超类的方法?

例如,我想找出一个类有它自己的执行isEqual:hash,而不是依赖于一个超类.

cocoa introspection objective-c objective-c-runtime

7
推荐指数
1
解决办法
216
查看次数