private method in ObjC

关于ObjC的private method,一直不太确定其规则,故用程序测试一下。

 

定义三个类,MyClass, MySubClass, MyOtherClass. 其中MySubClass继承自MyClass, MyOtherClass独立存在。

 

关于private method有两种说法,一说使用category来实现,即在.m文件中如下书写,

 

@interface MyClass()

- (void)privateMethod;

@end

 

另一说法是直接在@implement里书写函数,而不在.h中定义即可达到private目的,即

 

@implement MyClass

 

- (void)privateMethod {

NSLog(@"privateMethod called");

}

 

@end

 

究竟这两种方法有没有不同?private究竟有多private?请往下看。

 

首先,我把MyClass, MySubClass, MyOtherClass以及test driver分别放在不同的.m文件中,一个4个文件,结果是

 

1. 在test driver中生成三个instance,

 

MyClass* myObj;

MySubClass* mySubObj;

MyOtherClass* myOtherObj;

 

对myObj调用privateMethod, 即

[myObj privateMethod];

 

结果,编译出错。OK, 和传统的private行为一致。

 

2. 使用NSObject的performSelector调用privateMethod,即,

 

    [myObj performSelector:@selector(privateMethod)];    

    [mySubObj performSelector:@selector(privateMethod)];

 

 

结果,编译通过(必然的),调用成功——console上印出privateMethod called。

 

接下来,将MyClass, MySubClass, MyOtherClass全部放在一个.m中实现,加上test driver,一个2个文件,结果是,

 

1. 还是在test driver中生成三个instance,  对myObj调用privateMethod, 即

[myObj privateMethod];

 

结果,编译仍然出错。OK,没有疑问。(不论是使用category方式还是直接书写方式实现private都一样)

 

2. 在MySubClass中加入public方法,并在其中调用父类MyClass的privateMethod,如下,

 

-(void)printSubClass {

[self privateMethod];

}

 

然后在test driver中调用MySubClass的printSubClass method,即

[mySubObj printSubClass];

 

结果,编译通过!调用正常!(不论是使用category方式还是直接书写方式实现private都一样)

 

3. 测试2已经让我看到一些眉目,接下来再夸张一点,在MyOtherClass中中加入public方法,生成一个MyClass的instance,并调用privateMethod,即

 

-(void)printMyOtherClass {

    MyClass* myObj = [[MyClass alloc] init];

    [myObj privateMethod];

}

 

 

然后在test driver中调用MyOtherClass的printMyOtherClass method,即

[myOtherObj printMyOtherClass];

 

结果,编译仍然通过!调用仍然正常!

 

 

根据以上结果,大胆猜测,

 

1. 和继承不一样,ObjC所谓的private method只是文件作用域的问题,只要在同一文件中,就可以访问到,并没有在object system中维护这样一个标志

2. 结论1仅对于method call方式有意义,即[obj method]方式有文件作用域问题

3. 因为ObjC根本没有语言级的private method,所以performSelector可以call到类里的所有method

4. method call方式有文件作用域问题,可见method call仍然是编译时binding的,为了效率?performSelector则是完全的dynamic-binding

5. 使用category方式和直接书写方式实现private效果是一样的

 

 

肤浮理解,欢迎斧正!

 

P.S: 后话,找到一篇比较权威的资料,里面写到,

Methods can only be public. However, it is possible to mimic the private mode, by implementing some methods in the @implementation, without declaring them in the @interface, or using the notion of class category.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值