利用Objective-C分类对“私有成员,方法”的静态动态实现

分类


分类(category)是OBJ-C语法中非常方便的一部分,可以在运行时向某个现有类添加新的方法。包括Cocoa框架中的任何类,我们都可以对其进行扩展,这是从Smalltalk(oc的鼻祖)继承过来的,跟C#中的扩展方法比较像。

不谈历史,先来看下用分类进行私有成员的表现。

#import "ViewController.h"

@interface ViewController ()
{
    UIButton *button1;
}

@end

比如这里在.m文件,ViewController的上面有一个匿名的分类(类的扩展),这里声明的变量都属于我们的“私有成员”,对外属于隐藏状态。


这样,我们可以进行更多元化的定义,比如“公有可读,私有读写”。

.h文件中声明一个状态属性

@property (nonatomic, readonly) BOOL viewState;


然后在.m文件的匿名分类中对其声明为readwrite, 便可以进行读写操作了。


@interface ViewController ()
{
    UIButton *button1;
}

@property (nonatomic, readwrite) BOOL viewState;

@end

@implementation ViewController

- (void)setViewState:(BOOL)viewState
{
    code...
    return ;
}

- (BOOL)viewState
{
    code...
    return ;
}

于是,对属性信息的封装便完成了。


添加“成员”的动态实现


利用Runtime可以很好的在分类中添加属性,甚至对其进行设值取值。
这里我已有一个Person类,我想对其增加一个Address分类,并在分类中声明一个属性Address。

@interface Person (Address)

@property (nonatomic, strong) NSString *address;

@end

这样,我就必须对其进行设值取值了,嗯,但是它只是一个分类声明的属性,并不是成员。

于是代码可能就变成了下面这样

- (NSString *)address
{
    return self.address;
}

= =于是,我们找到了更好的方法,就是利用runtime的关联引用

static char KPersonAddressKey;
//setter
- (void)setAddress:(NSString *)address
{
    objc_setAssociatedObject(self, &KPersonAddressKey, address, OBJC_ASSOCIATION_COPY);
}
//getter
- (NSString *)address
{
    return objc_getAssociatedObject(self, &KPersonAddressKey);
}

下面对其进行了测试

        Person *p = [[Person alloc] init];
        p.address = @"Tianjin University";
        
        NSLog(@"%@", p.address);

打印结果
2013-08-09 00:41:43.033 CatagoryTest[788:303] Tianjin University

那,有没有私有方法呢。。。


有很多使用类的扩展来写私有方法的例子,这些都能够混过编译器进行调用,虽然编译器不会提示,但是还是会从类中找到那个方法并进行调用。

这主要得益于OC是一门动态语言,他的消息转发机制让很多事情都成为了可能,实现的同时甚至还提升了性能。
有时我们也管其叫“蹦床”,讲一个消息从一个对象弹到另一个对象。这种技术允许一个代理对象把消息转移到另一个线程,缓存结果,合并重复消息甚至其他中间的配置。

实现主要使用对 methodSignatureForSelector:以及forwadInvocation:的方法的覆写。

这里大家也可以参见念茜的博客Objective-C 的“多继承”



以上为全部内容,欢迎指正和扩充。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值