从语法上讲它是C的超集.但是由于消息是在运行时发送和处理的,这意味着它不能像c这样的纯编译语言,但它需要像Visual Basic或.Net运行时这样的运行时.
那么是什么阻止它通过将此运行时转换为.NET Framework或Java JVM之类的东西来移植到其他平台?
注意:当我说VB时它当然是最后一个版本6编译成字节码所以为什么你假装Java或.Net与VB6基本不同,除了可移植性它是相同的原则:看到类似于Java,Visual Basic编译成一个中间语言称为"字节码".字节码由Visual Basic运行时模块转换为x86机器语言.
阅读更多:http://www.answers.com/topic/visual-basic#ixzz19iJd3wjA
与Java类似,Visual Basic被编译为称为"字节码"的中间语言.字节码由Visual Basic运行时模块转换为x86机器语言.
我设置了一个类,理想情况下将读取传入的任何类的方法,然后在运行时将它们全部映射到单个选择器,然后将它们转发到原始选择器。
这现在确实有效,但我一次只能使用一种方法。问题似乎是,一旦我调整第一个方法,我用于捕获和转发该方法的 IMP 现在已与其他方法 IMP 交换。任何进一步的尝试都会搞砸,因为他们使用新交换的 IMP 来替换其他 IMP。
1)所以我有MethodA、MethodB和CustomCatchAllMethod。
2)我将 MethodA 与 CustomCatchAllMethod 交换。方法A->自定义CatchAll方法,自定义CatchAll方法->方法A
3)现在我尝试用CustomCatchAllMethod交换到MethodB,但是由于CustomCatchAllMethod现在= MethodA,MethodB变成MethodA和MethodA->MethodB。
那么,如何为每个我想要拦截的新选择器获取/复制 IMP 的新实例呢?
这是上述流程的粗略模型:
void swizzle(Class classImCopying, SEL orig){
SEL new = @selector(catchAll:);
Method origMethod = class_getInstanceMethod(classImCopying, orig);
Method newMethod = class_getInstanceMethod(catchAllClass,new);
method_exchangeImplementations(origMethod, newMethod);
}
//In some method elsewhere
//I want this to make both methodA and methodB point to catchAll:
swizzle(someClass, @selector(methodA:));
swizzle(someClass, @selector(methodB:));
Run Code Online (Sandbox Code Playgroud) 有没有办法找出 - 在运行时 - 给定的方法是否是可变类型?喜欢的东西method_getTypeEncoding(); 这不会告诉我方法是否接受可变数量的参数.或者是否有一个技巧可以这么说?
runtime objective-c variadic-functions objective-c-runtime method-signature
假设您有一个类“Foo”,其属性为“testProperty”。目的是获取属性名称(而不是值)NSString。问题可能与Get property name as a string重复。但这些答案对我没有帮助,因为:
NSStringFromSelector(@selector(prop))- 无论如何你必须输入字符串。假设我有一个类似的函数
- (NSString *)propertyToString:(id)propertyOfObject
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我可以使用,例如,排序
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:[self propertyToString:foo.testProperty] ascending:NO];
Run Code Online (Sandbox Code Playgroud)
所以最后,代码将会变得干净。
properties introspection objective-c objective-c-runtime ios
OBJC_ASSOCIATION_ASSIGN的第四个参数是否objc_setAssociatedObject表示原子或非原子?
该枚举定义为
enum {
OBJC_ASSOCIATION_ASSIGN = 0,
OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1,
OBJC_ASSOCIATION_COPY_NONATOMIC = 3,
OBJC_ASSOCIATION_RETAIN = 01401,
OBJC_ASSOCIATION_COPY = 01403
};
Run Code Online (Sandbox Code Playgroud)
是做什么用的@property(assign, atomic) id idAssignAtomic;?
是做什么用的@property(assign, nonatomic) id idAssignNonatomic;?
只要Swift类从NSObject扩展,我们就可以将它传递给Objective-C运行时并要求它为我们内省.
我们有三种选择:
..但是课程被打破了.(见图).为什么是这样?

我正在我的项目上设置单元测试,以确保所有UIViewController IBOutlets都连接到它们各自的Xib对象(即,在viewDidLoad之后不为零)。我正在考虑将协议与这些UIViewControllers一起使用所需的函数“ getAllOutletNames”,像这样:
-(NSArray*)getAllOutletNames
{
return @[ @"outletproperty1", @"outletProperty2", ...];
}
Run Code Online (Sandbox Code Playgroud)
...然后使用[viewController valueForKey:outletName]确保所有这些都不为零。问题在于它有点笨拙。必须为添加到xib的每个插座更新“ getAllOutletNames”,这很容易被忽略。我希望以编程方式进行此操作,以便可以自动检测并迭代所有IBOutlet属性。
我在NSHipster的这篇文章(“属性支持的属性”的cmd + f)中读到了一个属性应用于IBOutlets(或者我不太理解的“属性支持的属性”)。
看来我可以使用此答案的一部分获取类中所有属性的列表,而我可以使用此答案的一部分获取其属性。但是,使用以下代码从IBOutlet属性与非IBOutlet属性输出属性,我没有发现任何区别:
const char * type = property_getAttributes(class_getProperty([self class], [outletName UTF8String]));
NSString * typeString = [NSString stringWithUTF8String:type];
NSArray * attributes = [typeString componentsSeparatedByString:@","];
NSLog(@"%@",attributes);
Run Code Online (Sandbox Code Playgroud)
IB插座
(
"T@\"UILabel\"",
"&",
N,
"V_titleLabel"
)
Run Code Online (Sandbox Code Playgroud)
非IB插座
(
"T@\"UIView\"",
"&",
N,
"V_programmaticallySetupView"
)
Run Code Online (Sandbox Code Playgroud)
是否有任何方法可以访问NSHipster文章中提到的“属性支持的属性”,或者以其他方式确定某个属性是否以编程方式是IBOutlet,还是我在这里吠叫了错误的树?
最近,我正在研究Objective-C中的运行时.
我创建了一个名为的类TO:
@interface TO : NSObject
@end
#import "TO.h"
@implementation TO
- (id)forwardingTargetForSelector:(SEL)aSelector {
NSLog(@"%@ sel: %@", NSStringFromSelector(_cmd), NSStringFromSelector(aSelector));
return nil;
}
- (BOOL)respondsToSelector:(SEL)aSelector {
NSLog(@"%@ sel: %@", NSStringFromSelector(_cmd), NSStringFromSelector(aSelector));
return NO;
}
+ (BOOL)resolveClassMethod:(SEL)sel {
NSLog(@"%@ sel: %@", NSStringFromSelector(_cmd), NSStringFromSelector(sel));
return NO;
}
+ (BOOL)resolveInstanceMethod:(SEL)sel {
NSLog(@"%@ sel: %@", NSStringFromSelector(_cmd), NSStringFromSelector(sel));
return NO;
}
+ (IMP)instanceMethodForSelector:(SEL)aSelector {
NSLog(@"%@ sel: %@", NSStringFromSelector(_cmd), NSStringFromSelector(aSelector));
return nil;
}
- (void)forwardInvocation:(NSInvocation *)anInvocation {
NSLog(@"%@", NSStringFromSelector(_cmd));
}
@end
Run Code Online (Sandbox Code Playgroud)
然后,我在某个地方调用一个未经识别的选择器:
TO *to = …Run Code Online (Sandbox Code Playgroud) 目前swizzling正在Objective-C中尝试方法,我有一个问题.我试图理解方法混合的正确方法,在网上研究后我偶然发现了这个NSHipster帖子:http://nshipster.com/method-swizzling/
在帖子中,作者有一些方法调整样本代码.我正在寻找有人能够更好地向我解释作者正在做什么.特别是我对didAddMethod逻辑感到困惑.为什么作者不仅仅是直接的swapping/exchanging方法实现?我唯一的理论是,可能还有一些机会viewWillAppear:尚未加入UIViewController's method dispatch_table.特别是如果可能先将类别加载到内存中UIViewController......这是为什么?看起来很奇怪?只是寻找更多洞察力/清晰度,谢谢:)
快速代码如下:
func swizzleMethod()
{
let method:Method = class_getInstanceMethod(object_getClass(self), Selector("function1"))
self.function1()
let swizzledMethod:Method = class_getInstanceMethod(object_getClass(self), Selector("function2"))
method_exchangeImplementations(method, swizzledMethod)
self.function1()
}
func function1()
{
print("function1 log")
}
func function2()
{
print("function2 log")
}
Run Code Online (Sandbox Code Playgroud)
它记录:
function1 log
function1 log
Run Code Online (Sandbox Code Playgroud)
///// 我的环境是基于swift的项目,xcode7.2
这个总是碰到funtion1方法体,所以我认为交换失败了,这两个方法在同一个类中,有谁知道为什么?
objective-c ×8
ios ×2
properties ×2
swift ×2
swizzling ×2
.net ×1
c ×1
runtime ×1
unit-testing ×1