标签: objective-c-runtime

如何使用可变数量的参数调用实现?

为了简化,假设我有这样的功能

void myFunc(id _self, SEL _cmd, id first, ...)
{

}
Run Code Online (Sandbox Code Playgroud)

在那个方法中,我想在_self的超类上调用实现(imp).我可以使用以下代码访问IMP:

Class class = object_getClass(_self);
Class superclass = class_getSuperClass(class);
IMP superimp = class_getMethodImplementation(superclass, _cmd);
Run Code Online (Sandbox Code Playgroud)

现在,我怎么能打电话给那个imp?

objective-c objective-c-runtime

6
推荐指数
1
解决办法
1172
查看次数

如何在没有Foundation的情况下分配新对象?

我想构建一个没有Foundation的简单Objective C程序.我试过了:

#include <stdio.h>

@interface Foo{
    char * bar;
}
-(void)hello;
@end

@implementation Foo
-(void)hello {
    printf("Hello world!");
}
@end

int main(){
    Foo * foo = [Foo alloc];
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

然后它告诉我Foo may not respond to +allocautorelease called without pool...

如何在不使用allocFoundation的情况下初始化对象?

objective-c objective-c-runtime

6
推荐指数
1
解决办法
941
查看次数

什么是 objc_selector 实现?

我发现该SEL类型具有下一个定义:

typedef struct objc_selector *SEL;
Run Code Online (Sandbox Code Playgroud)

但我找不到如何objc_selector实施。

好的,如果我们有下一个代码

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
  SEL mySelector = NSSelectorFromString(@"mySelector");
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

, thenmySelector只是一个指针。在它包含的地址之后,我们看到了 C 字符串,它可以显示为:

const char* mySelector = "mySelector";
Run Code Online (Sandbox Code Playgroud)

objc_selector不是 C 字符串,它是结构,它可以包含其他内容。所以我想知道objc_selector结构是如何实现的。

macos objective-c objective-c-runtime selector ios

6
推荐指数
1
解决办法
1920
查看次数

swift 块的 `objc_method_description.types` 的格式是什么?

Swift 编译器为带有块的 swift 方法生成的 Objective-C 方法编码似乎使用了任何地方都没有记录的语法。

例如方法:

func DebugLog2(message: String) async -> String
Run Code Online (Sandbox Code Playgroud)

有方法编码:

v32@0:8@"NSString"16@?<v@?@"NSString">24

并且文档中至少有三个字符("<和)未涵盖:>

https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html

该类NSMethodSignature也不喜欢这种编码:

[NSMethodSignature signatureWithObjCTypes:"\"NSString\"16@?<v@?@\"NSString\">24"];
Run Code Online (Sandbox Code Playgroud)

结果是:

'+[NSMethodSignaturesignatureWithObjCTypes:]: '"NSString"16@?<v@?@"NSString">24'' 中不支持类型编码规范 '"'

我尝试查看 Swift 的代码,似乎有一种叫做“扩展方法类型编码”的东西:

https://github.com/apple/swift/blob/c2fc7ee9e72e9a39854548e3202c667e4934dc65/test/IRGen/objc_methods.swift#L13-L14

但我在试图找出 Swift 代码库中方法类型编码生成的位置时迷失了方向。

不回答此问题的相关问题:

示例代码:

decodeProto()

@objc
class TestClass : NSObject {
    @objc
    func DebugLog(message: String) -> String {
        print(message)
        return message
    }

    @objc
    func DebugLog2(message: String) async -> String {
        do {
            try await Task.sleep(nanoseconds: 1_000_000_000)
        } catch {}
        print(message); …
Run Code Online (Sandbox Code Playgroud)

objective-c objective-c-runtime method-signature swift

6
推荐指数
1
解决办法
133
查看次数

动态添加方法

我正在尝试在Obj-c运行时引用中找到此方法

BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types)
Run Code Online (Sandbox Code Playgroud)

我想添加一个新的方法,如:

- [AClass drawWithFrame:(NSRect)rect inView:(id)view]
Run Code Online (Sandbox Code Playgroud)

到目前为止,我已经编写了一个C函数:

void drawWithFrameInView(id this, SEL this_cmd, NSRect frame, id view){
...
} 
Run Code Online (Sandbox Code Playgroud)

现在我准备做了:

BOOL success = class_addMethod(NSClassFromString(@"AClass"), 
                               @selector(drawWithFrame:inView:), 
                               (IMP)drawWithFrameInView, 
                               "v@:@:@:");
Run Code Online (Sandbox Code Playgroud)

但是success从来没有,我尝试了同样的方法,使用更简单的签名方法,并且它有效.所以我认为问题是最后一个参数:"v@:@:@:"

在这种情况下我应该通过什么才能使我的新方法有效?

cocoa objective-c objective-c-runtime

5
推荐指数
1
解决办法
2253
查看次数

objc_getProtocol()为`NSApplicationDelegate"返回NULL?

我正在尝试使用该objc_getProtocol()函数来获取对表示NSApplicationDelegate协议的结构的引用:

Protocol *protocol = objc_getProtocol("NSApplicationDelegate");
Run Code Online (Sandbox Code Playgroud)

但是,出于某种原因,这总是会回归NULL.

其他协议,如NSObject,NSCoding,NSTableViewDelegate,和NSTableViewDataSource做工精细.

有什么特别之处NSApplicationDelegate,或者我做错了什么?

cocoa protocols objective-c objective-c-runtime nsapplication

5
推荐指数
1
解决办法
684
查看次数

我的混合打破了KVO

我正在尝试实现isa调配,因为我需要在某些对象的dealloc方法中执行某些操作.我压倒一切 - (班级)班级; 返回原始类的方法(如KVO所做).一切正常,直到我尝试将观察者添加到混合对象.它只是崩溃了.

  1. 0x00000000(0x00000000)()
  2. _NSKeyValueRetainedObservationInfoForObject()中的0x0091d22a
  3. 0x0092ec88 in - [NSObject(NSKeyValueObserverRegistration)_addObserver:forProperty:options:context:]()
  4. 0x0092d6fd in - [NSObject(NSKeyValueObserverRegistration)addObserver:forKeyPath:options:context:]()

这是实施调酒

- (void)swizzleClass
{
    NSString *proxyClassName = [NSString stringWithFormat:@"MDSwizzled_%@", NSStringFromClass(self->isa)];
    Class proxyClass = NSClassFromString(proxyClassName);

    if (!proxyClass)
        proxyClass = [self createProxyClassWithName:proxyClassName];

    object_setClass(self, proxyClass);
}

- (Class)createProxyClassWithName:(NSString *)proxyClassName
{
    const char *c_proxyClassName = [proxyClassName cStringUsingEncoding:NSUTF8StringEncoding];
    Class proxyClass = objc_allocateClassPair(self->isa, c_proxyClassName, 0);

    Class dummyClass = [MDDummy class];
    class_addMethodFromClass(proxyClass, dummyClass, @selector(dealloc));
    class_addMethodFromClass(proxyClass, dummyClass, @selector(class));

    objc_registerClassPair(proxyClass);
    return proxyClass;
}
Run Code Online (Sandbox Code Playgroud)

MDDummy它只是一种令人信服的类保持方法(这与添加原始函数没有区别).

@implementation MDDummy
- (void)dealloc
{

    //Special thinngs

    [super dealloc];
}

- …
Run Code Online (Sandbox Code Playgroud)

objective-c objective-c-runtime key-value-observing swizzling isa-swizzling

5
推荐指数
1
解决办法
2199
查看次数

如何在NSObject中实现保留计数?

我的问题是当前版本的Foundation(或Objective-C运行时库,因为它似乎在那里)如何实现NSObject派生对象的保留计数?正如我在NSObject.mm上看到的那样,retain countNSObject界面体中没有调用ivar .相反,似乎有一种表或映射包含每个对象的引用计数器.但是,如果保留计数真的与地图做,是不是retainrelease行动与这种实现(因为太贵了,在这种情况下,有必要锁定和解锁互斥,查找地图,找到合适的对象,除了事实那么,在多线程环境中,一次只能保留/释放一个对象)?

我没有找到相关的新对象的分配时,保留计数器设置为1东西,无论是在_objc_rootAllocWithZoneNSObject.mm(这似乎是被调用的函数[NSObject alloc])也不_class_createInstanceFromZoneobjc-runtime-new.mm(即后来被称为_objc_rootAllocWithZone.

cocoa objective-c objective-c-runtime nsobject retaincount

5
推荐指数
1
解决办法
867
查看次数

在方法中反省当前块上下文àla_cmd

对我来说,Objective-C能够对周围环境做出反应,描述和混乱,这就是它所处的位置.这从基础层面开始,具有坚定不移的能力,可以随时参考_cmd并获得最新信息SEL.从那里,你NSInvocation可以选择参加什么咒语或运行时诡计.

现在,在一个区块内,您仍然可以调用_cmd并获得当前"上下文"的模糊描述,即

__30-[RoomController awakeFromNib]_block_invoke123RoomController
Run Code Online (Sandbox Code Playgroud)

描述?是. 信息化?好的......但不是那么有用.如何获得动态和准确的运行时信息,特别是调用签名,args等?

我找到了一个有用的小方法来提前"描述"一个块,它提供了一个很好的例子,说明我希望在块中获取信息的类型.

typedef void(^blockHead)(NSString*);
blockHead v = ^(NSString*sandy) {  NSLog(@"damnDog",nil); };
Log([v blockDescription]);

[v blockDescription] = <NSMethodSignature: 0x7fd6fabc44d0>
    number of arguments = 2
    frame size = 224
    is special struct return? NO
    return value: -------- -------- -------- --------
        type encoding (v) 'v'
        flags {}
        modifiers {}
        frame {offset = 0, offset adjust = 0, size = 0, size …
Run Code Online (Sandbox Code Playgroud)

introspection objective-c objective-c-runtime objective-c-blocks

5
推荐指数
1
解决办法
435
查看次数

Swift 2.0复制OBJC_ASSOCIATION_RETAIN

我正在扩展Swift 2.0中的一些类来使用ReactiveCocoa 3.0(swift-2.0分支),但是遇到了一些麻烦.

我跟随了Colin Eberhardt的教程,并将他的部分UIKit扩展逻辑复制粘贴到我的OS X应用程序中.除了这个属性之外,它都编译得很好:UInt(OBJC_ASSOCIATION_RETAIN),这给了我以下编译器错误.

使用未解析的标识符

我怎样才能访问这个属性?我试过import ObjectiveC#import <objc/runtime.h>在头文件中,但似乎没有任何工作.

func lazyAssociatedProperty<T: AnyObject>(host: AnyObject, key: UnsafePointer<Void>, factory: ()->T) -> T {
    return objc_getAssociatedObject(host, key) as? T ?? {
        let associatedProperty = factory()

        objc_setAssociatedObject(host, key, associatedProperty, UInt(OBJC_ASSOCIATION_RETAIN)) // <-- Use of unresolved identifier
        return associatedProperty
    }()
}
Run Code Online (Sandbox Code Playgroud)

objective-c-runtime swift swift2

5
推荐指数
1
解决办法
2630
查看次数