当前位置:  开发笔记 > 编程语言 > 正文

Objective-C的隐藏功能

如何解决《Objective-C的隐藏功能》经验,为你挑选了6个好方法。

Objective-C因其在Mac OS X和iPhone开发中的使用而得到越来越广泛的应用.Objective-C语言中您最喜欢的"隐藏"功能有哪些?

每个答案一个功能.

举一个示例和该功能的简短描述,而不仅仅是文档的链接.

使用标题作为第一行标记要素.

benzado.. 20

方法调酒

基本上,在运行时,您可以将方法的一个实现替换为另一个.

这是一个代码解释.

一个聪明的用例是延迟加载共享资源:通常你会sharedFoo通过获取一个锁来实现一个方法,foo如果需要的话创建它,获取它的地址,释放锁,然后返回foo.这确保了foo只创建一次,但每次后续访问都会浪费时间,而不再需要锁.

使用方法调配,你可以像以前一样做,除了一旦foo创建,使用swizzling交换初始实现sharedFoo与第二个没有检查,只是返回foo我们现在知道已创建的!

当然,方法调整可能会让你陷入麻烦,并且可能存在上述示例是一个坏主意的情况,但是嘿......这就是为什么它是一个隐藏的功能.



1> benzado..:

方法调酒

基本上,在运行时,您可以将方法的一个实现替换为另一个.

这是一个代码解释.

一个聪明的用例是延迟加载共享资源:通常你会sharedFoo通过获取一个锁来实现一个方法,foo如果需要的话创建它,获取它的地址,释放锁,然后返回foo.这确保了foo只创建一次,但每次后续访问都会浪费时间,而不再需要锁.

使用方法调配,你可以像以前一样做,除了一旦foo创建,使用swizzling交换初始实现sharedFoo与第二个没有检查,只是返回foo我们现在知道已创建的!

当然,方法调整可能会让你陷入麻烦,并且可能存在上述示例是一个坏主意的情况,但是嘿......这就是为什么它是一个隐藏的功能.



2> splattne..:

造像

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的每次调用.


从10.5开始,不推荐使用Class_poseAs.替换是在逐个方法的基础上做同样的事情,现在在运行时明确支持.

3> pfeilbr..:

对象转发/方法丢失

当一个对象被发送一个没有方法的消息时,运行时系统给它另一个机会来放弃之前处理该调用.如果对象支持-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.


我建议使用记录的方法' - [NSObject forwardInvocation:]`.未记录的方法` - [Object forward ::]`不再使用,现在在Objective-C运行时不再可用.例如iOS设备上的64位和ARM.

4> Brent Royal-..:

ISA交换

需要覆盖所有对象的行为?实际上,您可以使用一行代码更改活动对象的类:

obj->isa = [NewClass class];

这只会更改接收该对象的方法调用的类; 它不会更改内存中对象的布局.因此,只有当您拥有一组具有相同ivars(或具有其他人的子集的类)并且您想要在它们之间切换的类时,这才真正有用.

我编写的一段代码使用它来进行延迟加载:它分配一个类的对象A,填充几个关键的ivars(在这种情况下,主要是一个记录号)并将isa指针切换到指向LazyA.当比一个非常小的一组像其他任何方法releaseretain被调用,LazyA负载从磁盘中的所有数据,在完高德的填充,切换isa指针回A,并调用转发给真正的类.


@MattDiPasquale最佳答案是正确的 - 现代的方法是使用objc_setClass().

5> schwa..:
#include 

许多工具用于尝试在该头文件中跟踪内存泄漏,过早的deallocs等.



6> Marco..:

分类

使用Categories,您可以在不进行子类化的情况下将方法添加到内置类中.完整参考.

向常用类添加便捷方法很好,例如NSString或NSData.


很棒的提示,但不是很隐蔽...... :)
推荐阅读
mobiledu2402851323
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有