我是一位有能力的红宝石程序员.昨天我决定最终尝试使用Apple的Cocoa框架.帮我看看ObjC的方式吗?
我想围绕让我的头objc_allocateClassPair和objc_registerClassPair.我的目标是动态生成一些类,然后能够像任何其他类一样使用它们.这是否适用于Obj C?
分配和注册类后A,我在调用时遇到编译错误[[A alloc] init];(它说'A' Undeclared).我只能A使用运行时的objc_getClass方法实例化.有没有办法告诉编译器,A并像我一样传递消息NSString?编译器标志还是什么?
我有10个左右,其他类(B,C,...),都具有相同的超类.我想直接在代码中(消息他们[A classMethod],[B classMethod]......),而无需objc_getClass.我想在这里过于动态还是只是拙劣地实施我的实施?它看起来像这样......
NSString *name = @"test";
Class newClass = objc_allocateClassPair([NSString class], [name UTF8String], 0);
objc_registerClassPair(newClass);
id a = [[objc_getClass("A") alloc] init];
NSLog(@"new class: %@ superclass: %@", a, [a superclass]);
//[[A alloc] init]; blows up.
Run Code Online (Sandbox Code Playgroud) 在Interface Builder中,您可以选择缩放按钮图像的方式,为"缩放"下拉菜单选择"轴独立","按比例缩小"等.如何在运行时访问或更改NSButton的此属性?
在Objective-C运行时参考中,我看到class_addMethod但没有class_removeMethod.如何动态删除方法?
另外,class_addMethod添加实例方法还是类方法?
我正在使用Objective-C运行时库函数class_copyMethodList()来获取我班级中所有方法的列表.然后,我如何将那些类型的Method对象转换为可用的类型SEL对象?
我正在尝试为NSMethodSignature协议中声明的方法获取签名 - 对象或至少是类型编码字符串.
询问Protocol对象本身是不可能的,因为a)它没有实现methodSignatureForSelector:,而b)(如下面Kevin所述)它已被弃用.
运行时函数protocol_getMethodDescription返回a struct objc_method_description,文档中的任何位置都没有描述.它位于公共标题中,但是 - <objc/runtime.h>:
struct objc_method_description {
SEL name;
char *types;
};
Run Code Online (Sandbox Code Playgroud)
假设那里的types字符串将是与其他地方使用的相同类型的签名编码字符串似乎是合理的,例如预期的字符串+[NSMethodSignature signatureWithObjCTypes:],实际上它看起来是正确的.
我无法追踪的是该字符串与类型编码过程之间的实际可验证连接.
我不知道它会是什么,但是,我是否有任何理由依赖此types字符串在同一运行时与其他对象/函数的交互有效?请注意,我不是自己编写字符串或期望它们具有给定的格式或值 - 我只想将它们从运行时/框架的一部分传递给另一部分,即从协议中检索编码字符串和)NSMethodSignature如果一个对象不可用,则使用它来生成一个对象,并且可能b)将它与运行时生成的对象NSInvocation(即,in -forwardInvocation:)进行比较.
我有一个gdb脚本,我正在努力跟踪所有通过objc_msgSend的Objective-C方法调用,但我遇到了一个我似乎无法处理的问题.在查看了Objective-C运行时源代码之后,我开发了以下脚本,以便在objc_msgSend的每个中断处打印[].问题是在某些情况下data_NEVER_USE不是有效指针但也不是null.我能找到一个类是否被初始化的唯一指标是id-> data_NEVER_USE-> flags&RW_REALIZED.我在这里错过了类初始化的哪些方面,这将允许我跳过这种情况?
b objc_msgSend
c
commands
silent
if (*$r0 == 0)
continue
end
set $id = (class_t *)$r0
set $sel = $r1
print *$id
if($id->data_NEVER_USE != 0)
set $data = (class_ro_t *) ($id->data_NEVER_USE)
if (($data->flags & 0x80000000) && ($data->name))
set $classname = $data->name
printf "[%s ", $classname
else
continue
end
end
if ($sel != 0)
printf "%s", $sel
else
printf "null"
end
printf "]\n"
continue
end
Run Code Online (Sandbox Code Playgroud)
我很感激任何帮助.谢谢.
在objective-c运行时,类由以下结构表示:
typedef struct class_t {
struct class_t *isa; // Points to the class' meta class
struct class_t *super; // Points to the class' super class
Cache cache;
IMP *vtable;
union {
class_ro_t *rodata;
class_rw_t *rwdata;
};
} class_t;
Run Code Online (Sandbox Code Playgroud)
当一个MyClass类是一个根类而不是一个元类时,它的超级成员是一个NULL指针(这是可以理解的,因为它是一个根类,因此它没有超类).但是,如果我们得到同MyClass一根类的isa成员(指向MyClass'meta class),并且我们得到该isa成员的超级成员,它不是NULL指针,而是指向MyClass(不是元类)的指针.非元根类的元类的超类不应该是NULL指针(作为非元根类的超类)吗?既然不是,那它应该是什么?
我问这个是因为,事实上的方式,如果methodX是MyClass根类的实例方法(不是类方法),语句[MyClass methodX]
会调用methodX(它实际上是),不应该发生什么(再次,因为methodX是实例方法,而不是类方法,所以它不应该响应[MyClass methodX]语句).
在Objective C中,'self'是某个类的实例化.我怎样才能找出它是什么类的实例?我想要一个包含该类名称的NSString.我知道isKindOfClass但是只测试它是否是一个特定的类,我必须事先知道它的名字.如果我的应用程序(或50)中有20个类,我必须写出20个isKindOfClass语句来找出它是哪个类,并且我必须重写它们以在不同的应用程序中执行相同的测试.获得课程名称是否有更直接的方法?
另外,如何获取包含我在运行时所使用的方法名称的NSString?
我想在运行时调试方法中使用这些函数.
这个问题涉及Objective C和iOS.
我正在尝试执行以下操作,但是NSValue创建方法会返回nil.结构中的C位域是否不受支持?
struct MyThingType {
BOOL isActive:1;
uint count:7;
} myThing = {
.isActive = YES,
.count = 3,
};
NSValue *value = [NSValue valueWithBytes:&myThing objCType:@encode(struct MyThingType)];
// value is nil here
Run Code Online (Sandbox Code Playgroud) 为什么Objective-C编译器需要在编译时知道在将对象推迟到运行时(即动态绑定)时将在对象上调用的方法的签名?例如,如果我写[foo someMethod],为什么编译器需要知道签名someMethod?