我正在尝试实现一个基本的面向对象的ANSI C运行时并使用Objective-C作为指导.
它们似乎分为三部分.类描述,类接口和类实现.为了实例化类接口,只有运行时已使用类描述实例化类对象时,才能使用熟悉的使用Class对象实例化对象的方法.
那么在第一次运行时是否静态分配了所有类定义,以提供使用Class对象进行实例化的能力?或者如果它们是动态分配的(在初始调用时),如何?它是运行循环的一部分还是Class实际上是一个函数,它确定在转发消息之前是否已经分配了它?
这段代码给了我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++作为默认语言/编译器,此代码位于项目的最开始
多谢你们
我正在尝试使用该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",然后动态调用它:
如果它是一种类方法.然后调用它:objc_msgSend(objc_getClass("ClassName"),sel_registerName("SEL"));
如果它是一个实例方法,则在调用类中找到现有的类实例变量:objc_msgSend([self.classInstance,sel_registerName("SEL"));
所以我想知道是否有办法:
检查一个类是否有给定的方法(我发现"responseToSelector"将是一个)
检查类方法或实例方法中的给定方法(也可以使用responseToSelector)
我遇到了一个有趣的问题,并且无法在其上找到任何文档... 有时properties在a protocol中声明的未在符合该类的特定类中实现,protocol并且发生运行时异常.dynamic property在一些奇怪的情况下,定义是否被优化?不能protocols用于properties宣布dynamic?任何对此的见解将不胜感激.
以下是一些更多细节.
鉴于protocol:
@protocol MyProtocol <NSObject>
@property (nonatomic, strong) id someProperty;
@end
Run Code Online (Sandbox Code Playgroud)
和一个实现protocol类似的类:
@interface MyClass <MyProtocol>
@end
@implementation MyClass
@dynamic someProperty;
@end
Run Code Online (Sandbox Code Playgroud)
我注意到有时我无法从呼叫中获取任何信息
class_getProperty(myClass, propertyName);
Run Code Online (Sandbox Code Playgroud)
对于properties中protocol.这只发生在某些类中,似乎是零星的.
我正在运行最新的Xcode 4并链接到iOS 6 SDK.我确实在同一台机器上安装了预发布的Xcode 5,虽然它不是默认的(通过xcode-select).
如果您运行此代码:
@protocol MyProtocol <NSObject>
@property (nonatomic, strong) id someData;
@end
@interface MyObject : NSObject <MyProtocol>
@end
@implementation MyObject
@dynamic …Run Code Online (Sandbox Code Playgroud) 当应用程序(包括系统应用程序/服务器)调用System Framework(CoreServices.framework)时,我需要得到通知.我不确定Code Injection是否适用于系统范围的框架.
是否可以用我自己的副本替换系统框架,然后将消息转发给真实的副本?
在Objective-C的低级运行时头文件(/usr/include/objc)中,有一个objc-exceptions.h文件.这似乎这是怎么@try/ @catch由ObjC编译器实现的.
我试图手动调用这些函数(用于ObjC运行时和实现的实验),以捕获"发送到类的无法识别的选择器"异常.
所以基本上,所有我要找的是如何做一个例子@try/ @catch使用低级别的运行时函数.提前致谢!
exception-handling objective-c try-catch objective-c-runtime
鉴于我有一个由method_copyReturnType()返回的类型说明符.在随GCC提供的GNU运行时中,有各种方法可以使用类似的类型说明符objc_sizeof_type(),objc_alignof_type()以及其他类型.
使用Apple运行时时,没有这样的方法.
如何使用Apple运行时解释类型说明符字符串(例如获取类型的大小)而不为自己实现if/else或case开关?
[更新]
我无法使用Apple Foundation.
我正在研究如何将属性(在这种情况下为整数)添加到所有UIView实例,无论它们是否是子类.是否使用objc_setAssociatedObject()并objc_getAssociatedObject()在一个类别中以适当的Apple认可方式执行此操作?
我听说过一些关注,这构成了"运行时黑客",并且可能导致难以追踪和调试的问题.有没有人见过这类问题?有没有更好的方法在UIView没有子类化的情况下向所有实例添加整数属性?
更新:我不能只使用tag,因为这需要在已经tag用于其他事情的代码库中使用.相信我,如果我能用tag它,我会的!
Objective-C @encode生成C字符串来表示任何类型,包括基元和类,如下所示:
NSLog(@"%s", @encode(int)); // i
NSLog(@"%s", @encode(float)); // f
NSLog(@"%s", @encode(CGRect)); // {CGRect={CGPoint=ff}{CGSize=ff}}
NSLog(@"%s", @encode(NSString)); // {NSString=#}
NSLog(@"%s", @encode(UIView)); // {UIView=#@@@@fi@@I{?=b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b6b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b3b1b1b1b2b2b1}}
Run Code Online (Sandbox Code Playgroud)
因此,我可以使用一个有意义的类(包含类名称)编码@encode(ClassName),但它的格式与泛型的编码相同struct(如上例所示).
现在,我的问题是,给定任何(当然有效)类型编码,是否可以找出编码是否是Objective-C类,如果是,那么获取Class对应于该编码的对象?
当然,我大概可以只尝试解析类名出的编码类型,并从使用获取类NSClassFromString,但只是听起来并不像正确的方式去做,或者特别的性能效率.这真的是实现这一目标的最佳方式吗?
给出以下代码:
return TyphoonDefinition.withClass(AppDelegate.classForCoder()) {
(definition) in
definition.injectProperty("assembly")
})
Run Code Online (Sandbox Code Playgroud)
...有必要使用.classForCoder(),如同.class()被击倒.与简单相比,这当然不直观.class().有没有提供更好的可读性的替代方案?