为了简化,假设我有这样的功能
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?
我想构建一个没有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 +alloc和autorelease called without pool...
如何在不使用allocFoundation的情况下初始化对象?
我发现该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结构是如何实现的。
Swift 编译器为带有块的 swift 方法生成的 Objective-C 方法编码似乎使用了任何地方都没有记录的语法。
例如方法:
func DebugLog2(message: String) async -> String
Run Code Online (Sandbox Code Playgroud)
有方法编码:
v32@0:8@"NSString"16@?<v@?@"NSString">24
并且文档中至少有三个字符("、<和)未涵盖:>
该类NSMethodSignature也不喜欢这种编码:
[NSMethodSignature signatureWithObjCTypes:"\"NSString\"16@?<v@?@\"NSString\">24"];
Run Code Online (Sandbox Code Playgroud)
结果是:
'+[NSMethodSignaturesignatureWithObjCTypes:]: '"NSString"16@?<v@?@"NSString">24'' 中不支持类型编码规范 '"'
我尝试查看 Swift 的代码,似乎有一种叫做“扩展方法类型编码”的东西:
但我在试图找出 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) 我正在尝试在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@:@:@:"
在这种情况下我应该通过什么才能使我的新方法有效?
我正在尝试使用该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
我正在尝试实现isa调配,因为我需要在某些对象的dealloc方法中执行某些操作.我压倒一切 - (班级)班级; 返回原始类的方法(如KVO所做).一切正常,直到我尝试将观察者添加到混合对象.它只是崩溃了.
这是实施调酒
- (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
我的问题是当前版本的Foundation(或Objective-C运行时库,因为它似乎在那里)如何实现NSObject派生对象的保留计数?正如我在NSObject.mm上看到的那样,retain count在NSObject界面体中没有调用ivar .相反,似乎有一种表或映射包含每个对象的引用计数器.但是,如果保留计数真的与地图做,是不是retain和release行动与这种实现(因为太贵了,在这种情况下,有必要锁定和解锁互斥,查找地图,找到合适的对象,除了事实那么,在多线程环境中,一次只能保留/释放一个对象)?
我没有找到相关的新对象的分配时,保留计数器设置为1东西,无论是在_objc_rootAllocWithZone在NSObject.mm(这似乎是被调用的函数[NSObject alloc])也不_class_createInstanceFromZone在objc-runtime-new.mm(即后来被称为_objc_rootAllocWithZone.
对我来说,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
我正在扩展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)