标签: objective-c-runtime

Swift isa指针重映射或其他支持的方法调配

Swift类是否具有可以重新映射的isa指针?

我们已经看到Swift 使用比Objective-C 更静态的方法调度,它(除非来自Foundation/NSObject的类设备)在运行时基于重映射方法实现防止了调配风格.

我想知道我们将如何实现基于方法拦截的动态功能,如观察者模式,通知等?目前所有这些东西都是由Objective-C层提供的,可以很容易地集成到Swift中.但是,如果我们想在我们自己的框架(或应用程序)中提供这些类型的功能,是否有必要在Objective-C中实现它们?我认为有一种方法可以"原生"地完成它.

另一种对Objective-C来说很常见的混合是重新映射isa-pointer来动态生成一个子类.Swift是否支持这种调配?如果没有什么拦截任意的方法调用的支持呢?

编辑: 正如@jatoben指出的那样,从arm64开始重新映射必须通过调用object_setClass()而不是直接访问该值来完成.这仍然被称为'isa指针调配'

objective-c objective-c-runtime swift

12
推荐指数
1
解决办法
3068
查看次数

class_getClassVariable()做什么?

如果实例变量属于类的实例,那么类变量将属于元类的实例,我认为.但是我对Objective-C元类的经验告诉我,这不太可能.

我想知道class_getClassVariable相反的是什么class_getInstanceVariable,以及为什么class_setClassVariable运行时没有.

metaclass class objective-c objective-c-runtime class-variables

11
推荐指数
1
解决办法
1155
查看次数

如何获得具有编码的类型的大小?

给定Objective-C类型type,可以轻松获得该类型的编码 encoding和大小size:

const char *encoding = @encode(type);
size_t size = sizeof(type);
Run Code Online (Sandbox Code Playgroud)

换句话说,我们有映射

@encode: type_t -> const char *
sizeof:  type_t -> size_t
Run Code Online (Sandbox Code Playgroud)

这提出了两个问题:

(1)假设我们只有一个编码,而不是一个类型.获得映射会很不错

sizeofencodedtype: const char * -> size_t
Run Code Online (Sandbox Code Playgroud)

这样,对于每个type_t type我们都有

sizeofencodedtype(@encode(type)) = sizeof(type)
Run Code Online (Sandbox Code Playgroud)

这样的功能是否已经存在?如果没有,怎么可能建立一个?

(2)理想情况下,我们可以反转@encode映射来进行映射

decode: const char * -> type_t
Run Code Online (Sandbox Code Playgroud)

但这似乎不可能,因为type_t不是真正的C类型.我想我可以等待@decode添加到语言中,但这不是很现实或时间敏感.但是,如果不能使用其编码在运行时实例化类型吗?

参考文献: Objective-C运行时编程指南 - 类型编码

objective-c objective-c-runtime

11
推荐指数
1
解决办法
845
查看次数

Objective-C运行时如何检索类和方法列表?

如果我得到以下Objective-C源文件:

// test.m
#import <objc/Object.h>

@interface MySuperClass: Object {

}
-(void) myMessage1;
@end

@implementation MySuperClass
-(void) myMessage1 {

}
@end

@interface MyClass: MySuperClass {

}
-(void) myMessage2;
@end

@implementation MyClass
-(void) myMessage2 {

}
@end

int main() {

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

并尝试从中生成一个程序集文件clang -fobjc-nonfragile-abi -fnext-runtime -S test.m,我得到以下汇编代码:

    .file   "test.m"
    .text
    .align  16, 0x90
    .type   _2D__5B_MySuperClass_20_myMessage1_5D_,@function
_2D__5B_MySuperClass_20_myMessage1_5D_: # @"\01-[MySuperClass myMessage1]"
.Ltmp0:
    .cfi_startproc
# BB#0:
    movq    %rdi, -8(%rsp)
    movq    %rsi, -16(%rsp)
    ret
.Ltmp1:
    .size   _2D__5B_MySuperClass_20_myMessage1_5D_, .Ltmp1-_2D__5B_MySuperClass_20_myMessage1_5D_
.Ltmp2:
    .cfi_endproc
.Leh_func_end0:

    .align  16, …
Run Code Online (Sandbox Code Playgroud)

assembly objective-c objective-c-runtime

10
推荐指数
1
解决办法
1697
查看次数

Objective-C:什么是懒惰的课程?

查看Objective-C运行时库源代码,特别是在objc-runtime-new.mm,我看到了一些函数甚至注释引用了懒惰和非惰性类.似乎没有一个类+load的方法被称为懒类,但我不知道这一点,并最有可能是不正确的.在Google上搜索后,我没有在Objective-C上找到任何有关惰性类的内容.

那么,什么是Objective-C中的惰性类?Obj-C有这个功能吗?它是否与+load类实现中存在方法有关?在上面链接的文件中,运行时系统调用一个被调用的函数_getObjc2NonlazyClassList,以便从图像中获取非惰性类的列表.为什么没有_getObjc2LazyClassList功能呢?

objective-c lazy-evaluation objective-c-runtime

10
推荐指数
2
解决办法
826
查看次数

iOS/Objective-C:获取元类对象的正确方法

以下是获取元类的正确方法?

Class myMetaClass = objc_getMetaClass("NSString");
Run Code Online (Sandbox Code Playgroud)

要么:

Class myMetaClass = object_getClass([NSString class]);
Run Code Online (Sandbox Code Playgroud)
  • 它们有什么不同吗?

  • 正如第一个回答者在这里链接的另一篇文章所述:

请告诉我为什么(????) objc_getMetaClass();会在某些情况下详细破坏.

  • 在不同场景中使用它们的正确方法.

谢谢.

metaclass objective-c objective-c-runtime ios

10
推荐指数
1
解决办法
1852
查看次数

避免使用我的iOS框架和其中一个依赖项的项目中的重复符号的最佳方法是什么?

以下是其他帖子的引文:

我正在一个iOS项目中工作,该项目包括由另一家公司创建的静态库.该库包含旧版AFNeworking,我没有任何源文件.

现在我需要使用更新的(并且更少的bug)版本的afneworking,但我不能在项目中两次包括相同的类(当然)因为所有"重复的符号"

我的问题是我正在准备一个iOS框架,我想在将来避免这种情况.我不是在谈论AFNetworking,而是其他非常流行的iOS框架.另外,我在原始框架代码中应用了一些自定义更改.

避免"重复符号"和"类X在Y和Z中实现的一种方法.将使用其中一个",我想到的是在原始框架类中添加一些前缀,但是这是正确的解?

更新1:

我试图应用约翰的解决方案,但没有快乐.我创建了一个简化的项目(这里是repo的链接),它有两个类FrameworkClass,它只存在于框架目标中,而SharedClass存在于框架和应用程序目标中,所以也许你可以看看我是否在做某事错误.应用程序启动后,我仍然得到: objc[96426]: Class SharedClass is implemented in both .../TestFramework.framework/TestFramework and .../SymbolsVisibilityTest.app/SymbolsVisibilityTest. One of the two will be used. Which one is undefined

更新2:

这是我的输出nm基于提供的示例项目的框架输出:

0000000000007e14 t -[FrameworkClass doFramework]
0000000000007e68 t -[SharedClass doShared]
                 U _NSLog
                 U _NSStringFromSelector
00000000000081f0 s _OBJC_CLASS_$_FrameworkClass
                 U _OBJC_CLASS_$_NSObject
0000000000008240 s _OBJC_CLASS_$_SharedClass
00000000000081c8 s _OBJC_METACLASS_$_FrameworkClass
                 U _OBJC_METACLASS_$_NSObject
0000000000008218 s _OBJC_METACLASS_$_SharedClass
0000000000007fb0 s _TestFrameworkVersionNumber
0000000000007f70 s _TestFrameworkVersionString
                 U ___CFConstantStringClassReference
                 U __objc_empty_cache …
Run Code Online (Sandbox Code Playgroud)

objective-c static-libraries objective-c-runtime ios ios-frameworks

10
推荐指数
1
解决办法
2085
查看次数

作为AnyObject的Swift闭包

我试图使用这种方法:class_addMethod()在Obj-c中使用这样的方法:

class_addMethod([self class], @selector(eventHandler), imp_implementationWithBlock(handler), "v@:");
Run Code Online (Sandbox Code Playgroud)

我在Swift中使用它就像这样:

class_addMethod(NSClassFromString("UIBarButtonItem"), "handler", imp_implementationWithBlock(handler), "v@:")
Run Code Online (Sandbox Code Playgroud)

UIBarButtonItem正如您可能已经想到的那样,它是一个扩展.

imp_implementationWithBlock 采用类型的参数 AnyObject!

我怎么能()->()投入AnyObject

我试图像这样抛出它:handler as AnyObject但是它给了我一个错误说:()->() does not conform to protocol 'AnyObject'

objective-c objective-c-runtime ios swift

10
推荐指数
3
解决办法
5203
查看次数

基金会可以告诉我Objective-C方法是否需要特殊的结构返回?

我理解的背景:Objective-C方法调用基本上是一个带有两个隐藏参数(接收器和选择器)的C函数调用.Objective-C运行时包含一个名为objc_msgSend()的函数,该函数允许以这种方式调用方法.不幸的是,当函数返回结构时,可能需要一些特殊处理.有一些神秘的(有些人可能会说是疯狂的)规则来控制结构是否像其他值一样被返回,或者它是否实际上是通过引用在隐藏的第一个参数中返回的.对于Objective-C,还有一个名为objc_msgSend_stret()的函数必须在这些情况下使用.

问题:给定一个方法,NSMethodSignature或其他什么可以告诉我是否必须使用objc_msgSend()或objc_msgSend_stret()?到目前为止,我们已经发现NSMethodSignature知道这一点,它在调试输出中打印它,但似乎没有公共API.

如果你想回答"你为什么要这样做?!",请在阅读之前阅读以下内容:https://github.com/erikdoe/ocmock/pull/41

objective-c objective-c-runtime

9
推荐指数
1
解决办法
189
查看次数

在isa中存储东西

64位运行时消除了直接访问对象的isa字段的能力,这是CLANG工程师一直警告我们的事情.它们被一组相当具有创造性(且神奇)的ABI规则所取代,这些规则关于新命名的isa标题的哪些部分包含有关该对象的信息,甚至包含其他状态(在NSNumber/NSString的情况下).似乎存在一个漏洞,因为你可以选择退出新的"魔法"isa并使用你自己的一个(原始的isa),代价是通过某些运行时代码路径走慢路.

我的问题是双重的,然后:

如果可以选择退出并将object_setClass()任意类放入对象中+allocWithZone:,是否也可以在类的额外空间中放置任何内容,或者运行时是否会尝试通过快速路径读取它?

isa标题中究竟是什么标记为让运行时将它与正常的isa区分开来?

objective-c objective-c-runtime

9
推荐指数
2
解决办法
428
查看次数