如何在Objective-C中将readonly属性转换为readwrite属性?

前端之家收集整理的这篇文章主要介绍了如何在Objective-C中将readonly属性转换为readwrite属性?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
在Objective-C中将readonly属性转换为readwrite属性方法有哪些?请记住,我无法访问源代码.

原因:我需要在单元测试中进行此操作以进行模拟.

解决方法

如果没有访问类的主要实现块,或者至少包含它的编译单元,则无法更改此属性功能,因为您无法访问该单元外的ivar.即使你要在一个类别中为类添加一个setter,你也不可能完全影响类的存储,而不是完全在类之外.

但是,您可以使用KVC. setValue:forKey:如果可以找到一个,它将绕过setter并直接进入ivar.您可以使用它来设置您喜欢的任何值,即使是已经声明为readonly的属性,前提是您知道其名称的后备存储.

它是这样的:

  1. //Passaquisset.h
  2. #import <Foundation/Foundation.h>
  3.  
  4. @interface Passaquisset : NSObject
  5.  
  6. @property (copy,readonly,nonatomic) NSString * vanadium;
  7.  
  8. @end
  1. //Passaquisset.m
  2. #import "Passaquisset.h"
  3.  
  4. @implementation Passaquisset
  5.  
  6. @synthesize vanadium;
  7.  
  8. - (id) init {
  9.  
  10. self = [super init];
  11. if( !self ) return nil;
  12.  
  13. vanadium = @"Number 23";
  14.  
  15. return self;
  16. }
  17.  
  18. @end
  1. //Elsewhere...
  2. #import <Foundation/Foundation.h>
  3.  
  4. #import "Passaquisset.h"
  5.  
  6. int main(int argc,const char * argv[])
  7. {
  8.  
  9. @autoreleasepool {
  10.  
  11. Passaquisset * pq = [Passaquisset new];
  12. NSLog(@"%@",[pq vanadium]);
  13.  
  14. [pq setValue:@"Number 24" forKey:@"vanadium"];
  15.  
  16. NSLog(@"%@",[pq vanadium]);
  17.  
  18. }
  19. return 0;
  20. }

就像我说的那样,这会失败 – 实际上会引发一个异常 – 如果既没有一个setter也没有一个同名的ivar(或者附加一个下划线_vanadium(KVC非常聪明),比如该属性的值是完全计算的:

  1. //Passaquisset.m
  2.  
  3. #import "Passaquisset.h"
  4.  
  5. @implementation Passaquisset
  6.  
  7. /** KVC will fail with this version! **/
  8.  
  9. - (NSString *)vanadium
  10. {
  11. return @"Number 23";
  12. }
  13.  
  14. @end

为了完整起见,我要提一下,如果该属性由一个完全不同名称的ivar支持(例如@synthesize vanadium = erythronium;),您需要知道ivar的名称才能使用KVC.

猜你在找的C&C++相关文章