我很好奇是否有任何工具为此提供部分解决方案.由于performSelector,这是一个棘手的问题...但是工具应该至少能够提出候选人,使人类的工作变得更容易.
据我了解,未实现的方法通过以下方式解决:
这个三步流程定义在哪里?我想自己处理它,因为NSInvocation可能对我的需求来说太重了.我有一个围绕运行时源,并没有真正看到任何东西.
它看起来像旧的运行时会调用前进:args:在接收器上,这样做但似乎已经从新的运行时.我猜这个过程必须由框架而不是运行时定义,因为如果运行时依赖于Cocoa到需要NSInvocation来处理消息的程度,那就太奇怪了.是否可能是在NSObject/NSProxy上调用的无证方法?
编辑:
它看起来像运行时声明,但从未定义,当objc_msgSend找不到实现时调用的C函数:
id objc_msgForward(id object,SEL message,...);
我不为Apple工作,所以我不知道Foundation如何实现这一点,但至少在Cocotron的情况下,他们使用:
id objc_msgForward(id object,SEL message,...)
{
Class class=object->isa;
struct objc_method *method;
void *arguments=&object;
if((method=class_getInstanceMethod(class,@selector(forwardSelector:arguments:)))!=NULL)
return method->method_imp(object,@selector(forwardSelector:arguments:),message,arguments);
else
{
OBJCRaiseException("OBJCDoesNotRecognizeSelector","%c[%s %s(%d)]", class_isMetaClass(class) ? '+' : '-', class->name,sel_getName(message),message);
return nil;
}
}
Run Code Online (Sandbox Code Playgroud)
添加forwardSelector:arguments:方法似乎不起作用,所以我猜这是特定于Cocotron.有人知道objc_msgForward基金会做了什么吗?
有没有办法在运行时在目标c中为枚举值赋值?我有几个枚举,并希望每个枚举都有一定的价值.可以从xml文件中读取值.有没有办法做到这一点?
由于Objective-C是C超集,因此在编译.m文件期间,所有Objective-C特定语句都将转换为C语句(我猜是由预处理器).因此,例如,消息表达式[receiver method]转换为消息传递函数的调用objc_msgSend(receiver, selector).
我的问题是:如果我有这样的类定义:
@interface ClassA {
int var1;
float var2;
id var3;
}
-(void) method1;
-(int) method2: (int) num1;
@end
@implementation ClassA
-(void) method1 {
// Implementation of the method
}
-(int) method2: (int) num1 {
// Implementation of the method
}
@end
Run Code Online (Sandbox Code Playgroud)
它是由编译器转换成的(在Objective-C的2.0版本中)?它是转换成电话上一样的功能objc_allocateClassPair(),class_addIvar(),class_addMethod()并且objc_registerClassPair(),为了分别创建类,添加它的实例变量,增加它的方法和注册类,(所以该类结构在运行系统中实际定义,而不是被加载为从可执行文件中获取结构)?
在我的应用程序中,我有一个UIViewController我用了很多UIAlertView东西给用户询问的东西.
因为我需要每个人的响应UIAlertView我已经使我的控制器成为委托UIAlertViewDelegate,这工作正常但是在UIAlertView7'si`m试图找到更好的方式来使用委托.
在java中我知道我可以为一个目的创建内联类,就像在这个问题中:Java - 内联类定义
我想知道的是:有没有办法创建一个动态委托的类?实现这样的目标
id<UIAlertViewDelegate> myCustomClass = @class {
my class code goes here
}
UIAlertView* alertView;
alertView = [[UIAlertView alloc] initWithTitle:@"Title"
message:@"Message"
delegate:myCustomClass
cancelButtonTitle:@"No"
otherButtonTitles:@"OK", @"Sure", @"Maybe", nil] ];
[alertView show];
Run Code Online (Sandbox Code Playgroud) 使用Objective-C运行时库,我们如何确定对象是否是类对象而不是类的实例?
我试图检索我的类或其任何子类定义的所有属性的列表.以下代码片段是我一直使用的代码,它一直正常工作,直到最近的iOS8 beta 4.
if(!dictionary) {
dictionary = [NSMutableDictionary dictionary];
// Get all properties we have until we hit CBLNestedModel
while(klass != [CBLNestedModel class]) {
unsigned count;
objc_property_t* properties = class_copyPropertyList(klass, &count);
for (unsigned i = 0; i < count; i++) {
objc_property_t property = properties[i];
const char* propertyNameC = property_getName(property);
NSString* propertyName = [NSString stringWithUTF8String:propertyNameC];
const char* propertyAttrC = property_getAttributes(property);
NSString* propertyAttrS = [NSString stringWithUTF8String:propertyAttrC];
NSArray* propertyAttr = [propertyAttrS componentsSeparatedByString:@","];
NSLog(@"%@ has property %@", NSStringFromClass(klass), propertyName);
dictionary[propertyName] = propertyAttr;
} …Run Code Online (Sandbox Code Playgroud) 我使用它来获取属性名称的类:
- (Class)gm_classForPropertyName:(NSString *)propertyName {
objc_property_t prop = class_getProperty([self class], propertyName.UTF8String);
const char * attr = property_getAttributes(prop);
NSString *attributes = [NSString stringWithUTF8String:attr];
NSArray *components = [attributes componentsSeparatedByString:@"\""];
Class propertyClass;
for (NSString *component in components) {
Class class = NSClassFromString(component);
if (class) {
propertyClass = class;
break;
} else {
class = swiftClassMapping[component];
if (class) {
propertyClass = class;
break;
}
}
}
return propertyClass;
}
Run Code Online (Sandbox Code Playgroud)
但这是重要的部分:
objc_property_t prop = class_getProperty([self class], propertyName.UTF8String);
const char * attr = property_getAttributes(prop);
NSString *attributes …Run Code Online (Sandbox Code Playgroud) 使用Objective-C运行时,我可以获得@objc对象符合的所有协议的列表:
let obj = NSObject()
var pc: UInt32 = 0
let plist = class_copyProtocolList(object_getClass(obj), &pc)
print("\(obj.dynamicType) conforms to \(pc) protocols")
for i in 0 ..< Int(pc) {
print(String(format: "Protocol #%d: %s", arguments: [i, protocol_getName(plist[i])]))
}
Run Code Online (Sandbox Code Playgroud)
或者运行时加载的所有Objective-C协议:
var allProtocolCount: UInt32 = 0
let protocols = objc_copyProtocolList(&allProtocolCount)
print("\(allProtocolCount) total protocols")
for i in 0 ..< Int(allProtocolCount) {
print(String(format: "Protocol #%d: %s", arguments: [i, protocol_getName(protocols[i])]))
}
Run Code Online (Sandbox Code Playgroud)
但这些都没有列出任何Swift协议:
func == (lhs: MyClass, rhs: MyClass) -> Bool {
return lhs.value == rhs.value
} …Run Code Online (Sandbox Code Playgroud) 要在Swift中拥有一个关联对象,只需使用内存地址作为句柄,然后使用objc调用.
您可以在任何地方谷歌的常见示例代码是:
var keyA:UInt8 = 0
var keyB:UInt8 = 0
extension UIViewController {
var aoAA: String? {
get { return objc_getAssociatedObject(self, &keyA) as? String }
set { objc_setAssociatedObject(self, &keyA, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN) }
}
var aoBB: String? {
get { return objc_getAssociatedObject(self, &keyB) as? String }
set { objc_setAssociatedObject(self, &keyB, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN) }
}
}
Run Code Online (Sandbox Code Playgroud)
这工作正常,
class Thing: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
aoAA = "this is a"
print("...... \(aoAA)")
aoBB = "this is b"
print("...... \(aoBB)")
aoAA = …Run Code Online (Sandbox Code Playgroud)