Objective-C因其在Mac OS X和iPhone开发中的使用而得到越来越广泛的应用.Objective-C语言中您最喜欢的"隐藏"功能有哪些?
每个答案一个功能.
举一个示例和该功能的简短描述,而不仅仅是文档的链接.
使用标题作为第一行标记要素.
benzado.. 20
基本上,在运行时,您可以将方法的一个实现替换为另一个.
这是一个代码解释.
一个聪明的用例是延迟加载共享资源:通常你会sharedFoo
通过获取一个锁来实现一个方法,foo
如果需要的话创建它,获取它的地址,释放锁,然后返回foo
.这确保了foo
只创建一次,但每次后续访问都会浪费时间,而不再需要锁.
使用方法调配,你可以像以前一样做,除了一旦foo
创建,使用swizzling交换初始实现sharedFoo
与第二个没有检查,只是返回foo
我们现在知道已创建的!
当然,方法调整可能会让你陷入麻烦,并且可能存在上述示例是一个坏主意的情况,但是嘿......这就是为什么它是一个隐藏的功能.
基本上,在运行时,您可以将方法的一个实现替换为另一个.
这是一个代码解释.
一个聪明的用例是延迟加载共享资源:通常你会sharedFoo
通过获取一个锁来实现一个方法,foo
如果需要的话创建它,获取它的地址,释放锁,然后返回foo
.这确保了foo
只创建一次,但每次后续访问都会浪费时间,而不再需要锁.
使用方法调配,你可以像以前一样做,除了一旦foo
创建,使用swizzling交换初始实现sharedFoo
与第二个没有检查,只是返回foo
我们现在知道已创建的!
当然,方法调整可能会让你陷入麻烦,并且可能存在上述示例是一个坏主意的情况,但是嘿......这就是为什么它是一个隐藏的功能.
Objective-C允许类完全替换应用程序中的另一个类.替换类被称为"伪装成"目标类.然后,冒充类接收发送到目标类的所有消息.哪些类可以构成一些限制:
一个类只能构成其直接或间接超类之一
冒充类不得定义目标类中不存在的任何新实例变量(尽管它可以定义或覆盖方法).
在冒充之前,不得向目标类发送任何消息.
与类别类似,构建允许全局扩充现有类.提出允许类别中缺少两个功能:
一个冒充类可以通过super调用重写方法,从而结合目标类的实现.
冒充类可以覆盖类别中定义的方法.
一个例子:
@interface CustomNSApplication : NSApplication @end @implementation CustomNSApplication - (void) setMainMenu: (NSMenu*) menu { // do something with menu } @end class_poseAs ([CustomNSApplication class], [NSApplication class]);
这会拦截setMainMenu到NSApplication的每次调用.
对象转发/方法丢失
当一个对象被发送一个没有方法的消息时,运行时系统给它另一个机会来放弃之前处理该调用.如果对象支持-forward ::方法,则运行时调用此方法,并向其传递有关未处理调用的信息.转发呼叫的返回值将传播回方法的原始调用方.
-(retval_t)forward:(SEL)sel :(arglist_t)args { if ([myDelegate respondsTo:sel]) return [myDelegate performv:sel :args] else return [super forward:sel :args]; }
来自Objective-C Pocket Reference的内容
这非常强大,并且在Ruby社区中大量用于各种DSL和rails等.起源于Smalltalk,它影响Objective-C和Ruby.
需要覆盖所有对象的行为?实际上,您可以使用一行代码更改活动对象的类:
obj->isa = [NewClass class];
这只会更改接收该对象的方法调用的类; 它不会更改内存中对象的布局.因此,只有当您拥有一组具有相同ivars(或具有其他人的子集的类)并且您想要在它们之间切换的类时,这才真正有用.
我编写的一段代码使用它来进行延迟加载:它分配一个类的对象A
,填充几个关键的ivars(在这种情况下,主要是一个记录号)并将isa
指针切换到指向LazyA
.当比一个非常小的一组像其他任何方法release
和retain
被调用,LazyA
负载从磁盘中的所有数据,在完高德的填充,切换isa
指针回A
,并调用转发给真正的类.
#include
许多工具用于尝试在该头文件中跟踪内存泄漏,过早的deallocs等.
分类
使用Categories,您可以在不进行子类化的情况下将方法添加到内置类中.完整参考.
向常用类添加便捷方法很好,例如NSString或NSData.