标签: objective-c-runtime

获取调用方法的对象

如果我在这样的随机类中有一个调用:

@implementation SomeClass

- (void) classMethodFoo
{
    int a = [SomeSingleton sharedInstance].aValue;
}

@end
Run Code Online (Sandbox Code Playgroud)

在里面SomeSingleton sharedInstance,有没有办法获得对调用此方法的对象的引用(当然没有调用传递self作为参数)?

objective-c objective-c-runtime

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

如何在Objective-c中获取运行时块类型元数据?

我正在编写一个类,您可以在其中注册一个对象和一个要观察的属性.当属性设置为非特性时nil,将调用已注册的回调选择器(如target-action).选择器可以具有三个不同的签名,并且根据注册的类型调用右边的签名.

这工作正常,但现在我想添加注册块而不是选择器作为"回调函数"的功能.是否可以找到所提供的块的函数签名并根据所提供的块的类型以不同方式处理回调?

例如:

- (void)registerCallbackBlock:(id)block
{
    if ([self isBlock:block] {
        if ([self isMethodSignatureOne:block]) { /* */ }
        else if ([self isMethodSignatureTwo:block]) { /* */ }
        else { assert(false); }  // bad Block signature

        block_ = block;  // assuming ARC code
    }
    else { assert(false); } // not a block
} 

- (void)callBlock 
{
    if ([self isMethodSignatureOne:block_] {
        block_(arg1_, arg2_);         // needs casting?
    }
    else if ([self isMethodSignatureTwo:block_) {
        block_(arg1_, arg2_, arg3_);  // needs casting?
    }
}
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

我知道我可以使用特定的 …

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

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

为什么这段代码给出EXC_BAD_ACCESS(使用IMP)

这段代码给了我EXC_BAD_ACCESS,为什么?

NSMutableDictionary  *d = [[NSMutableDictionary alloc] init];
IMP imp= [d methodForSelector:@selector(setObject:forKey:) ];
imp(d,  @selector( setObject:forKey:), @"obj", @"key");
Run Code Online (Sandbox Code Playgroud)

我刚刚开始使用IMP,第一次尝试..没有运气.不知道为什么我得到错误,也..在过去,当我得到EXC_BAD_ACCESS时,消息在控制台打印,这次错误行突出显示.

一些注意事项:ARC已启用,XCode 4.3.2,该项目使用Objective-C++作为默认语言/编译器,此代码位于项目的最开始

多谢你们

objective-c objective-c-runtime objective-c++

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

使用objc_msgSend调用实例方法

我正在尝试使用该objc_msgSend方法动态调用某个方法.假设我想从A类调用B类中的一些方法,B类中有两种方法:

- (void) instanceTestWithStr1:(NSString *)str1 str2:(NSString *)str1;
+ (void) methodTestWithStr1:(NSString *)str1 str2:(NSString *)str1;
Run Code Online (Sandbox Code Playgroud)

我可以在A类中成功调用类方法:

objc_msgSend(objc_getClass("ClassB"), sel_registerName("methodTestWithStr1:str2:"), @"111", @"222");
Run Code Online (Sandbox Code Playgroud)

我也可以成功地在A类中调用这样的实例方法:

objc_msgSend([[objc_getClass("ClassB") alloc] init], sel_registerName("instanceTestWithStr1:str2:"), @"111", @"222");
Run Code Online (Sandbox Code Playgroud)

但问题是要获得一个Class BI实例必须调用"initWithXXXXX:XXXXXX:XXXXXX"而不是"init",以便将一些必要的参数传递给B类来执行init的工作.所以我在类A中将ClassB的实例存储为变量:self.classBInstance = [[ClassB alloc] initWithXXXXX:XXXXXX:XXXXXX];

然后我这样调用方法(成功):

问题是,我想通过简单地应用类名和方法sel来调用方法,如"ClassName"和"SEL",然后动态调用它:

  1. 如果它是一种类方法.然后调用它:objc_msgSend(objc_getClass("ClassName"),sel_registerName("SEL"));

  2. 如果它是一个实例方法,则在调用类中找到现有的类实例变量:objc_msgSend([self.classInstance,sel_registerName("SEL"));

所以我想知道是否有办法:

  1. 检查一个类是否有给定的方法(我发现"responseToSelector"将是一个)

  2. 检查类方法或实例方法中的给定方法(也可以使用responseToSelector)

  3. 检查一个类是否有给定类的实例变量所以我可以调用一个实例方法,如:objc_msgSend(objc_getClassInstance(self,"ClassB"),sel_registerName("SEL"));

cocoa objective-c objective-c-runtime

7
推荐指数
2
解决办法
6441
查看次数

什么是class_setIvarLayout和class_getIvarLayout?

我试图在运行时动态创建objc类,我需要Ivar在创建的类中添加一些.我发现class_addIvar哪些应该做我想要的,但我也发现了这些功能:

  • class_setIvarLayout
  • class_getIvarLayout
  • class_getWeakIvarLayout
  • class_setWeakIvarLayout

文档并没有真正说出有关这些方法的任何有用信息,我也无法从网上找到任何有用的解释.那他们是什么?如果我想做点什么,我是否需要使用它们Ivar

objective-c objective-c-runtime

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

objc_setAssociatedObject如何工作?

因为我们知道,我们可以添加使用类别和运行方法,如在Objective-C的变量 objc_setAssociatedObjectobjc_getAssociatedObject.例如:

#import <objc/runtime.h>
@interface Person (EmailAddress)
@property (nonatomic, readwrite, copy) NSString *emailAddress;
@end

@implementation Person (EmailAddress)

static char emailAddressKey;

- (NSString *)emailAddress {
    return objc_getAssociatedObject(self, 
                                    &emailAddressKey);
}

- (void)setEmailAddress:(NSString *)emailAddress {
   objc_setAssociatedObject(self, 
                            &emailAddressKey,
                            emailAddress,
                            OBJC_ASSOCIATION_COPY);
}
@end
Run Code Online (Sandbox Code Playgroud)

但有人知道做什么objc_getAssociatedObjectobjc_setAssociatedObject做什么?我的意思是,我们添加到对象(这里self)的变量存储在哪里?和变量之间的关系self

objective-c objective-c-runtime objective-c-category

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

在Objective-C中,何时创建了元类对象和类对象?

在Objective-C中,什么时候是类对 - 元类对象和类对象,是什么时候创建的?它是在应用程序执行的开始还是在您第一次实例化类的第一个对象时?

objective-c objective-c-runtime

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

假装为Class的NSProxy不会在64位运行时中处理respondsToSelector

在OCMockito中,使用NSProxy实现测试双精度.实例中的双重实现-respondsToSelector:如下:

- (BOOL)respondsToSelector:(SEL)aSelector {
    return [_mockedClass instancesRespondToSelector:aSelector];
}
Run Code Online (Sandbox Code Playgroud)

但是对于一个类的实现-respondsToSelector:这样的双重实现:

- (BOOL)respondsToSelector:(SEL)aSelector {
    return [_mockedClass respondsToSelector:aSelector];
}
Run Code Online (Sandbox Code Playgroud)

这一切都适用于32位运行时.例如,如果_mockedClass[NSString class],则代理正确回答它响应选择器+pathWithComponents:

但在64位运行时,它崩溃了:

Crashed Thread:  0  Dispatch queue: com.apple.main-thread

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: EXC_I386_GPFLT

Application Specific Information:
objc[1868]: GC: forcing GC OFF because OBJC_DISABLE_GC is set

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   libobjc.A.dylib                 0x00007fff95cbffc6 cache_getImp + 6
1   libobjc.A.dylib                 0x00007fff95ccd1dc lookUpImpOrForward + 50
2   libobjc.A.dylib                 0x00007fff95ccd198 lookUpImpOrNil + …
Run Code Online (Sandbox Code Playgroud)

objective-c objective-c-runtime class-method nsproxy

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

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

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

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

cocoa introspection objective-c objective-c-runtime

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

声明协议@objc并使其符合纯Swift中的NSObjectProtocol有什么区别?

考虑两个Swift协议:

@objc protocol SomeProtocol { }

protocol SomeOtherProtocol: NSObjectProtocol { }
Run Code Online (Sandbox Code Playgroud)

声明Swift协议@objc或符合它的区别是什么NSObjectProtocol?我知道任何协议@objc都不会被桥接到Objective-C,但纯Swift应用程序中这两个声明之间的区别是什么?据我了解,@objc应符合SomeProtocolNSObjectProtocol通过顶层SwiftObject.

objective-c objective-c-runtime nsobject swift swift-protocols

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