2014-02-06 15 views
0

对不起我的疯狂需求,但我在我写的框架中创建了一堆属性专用协议。“模拟”一个实现属性专用协议的对象的最简单方法

@protocol SomePropertiesOfAnObjectThing <NSObject> 

@property (nonatomic, strong) NSString *larry; 
@property (nonatomic, strong) NSString *curly; 
@property (nonatomic, strong) NSString *moe; 

@end 

有没有一种方法,更重要的是一种简单的方法来“模拟”一个实现此协议的对象?

id<SomePropertiesOfAnObjectThing> thingy = [ProtocolObject fromProtocol:@protocol(SomePropertiesOfAnObjectThing)]; 

thingy.larry = @"fizz"; 
thingy.curly = @"buzz"; 
thingy.moe = @"bar"; 

的两件事情,我试图避免:

  1. 显式地创建一个新的类
  2. 第三方的依赖(如OCMock)

我洗澡的人谁可以用最多的选票向我展示干净而简单的方式(至少1)。

回答

0

我的幼稚的解决方法如下:

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector { 
    return [[self class] instanceMethodSignatureForSelector:@selector(foo:)]; 
} 

- (void)forwardInvocation:(NSInvocation *)anInvocation 
{ 
    NSString *argument; 
    [anInvocation getArgument:&argument atIndex:2]; 
    if (argument) { 
     NSString *setterName = NSStringFromSelector(anInvocation.selector); 
     NSRange range = NSMakeRange(3, [setterName length]-4); 
     NSString *propertyName = [[setterName substringWithRange:range] lowercaseString]; 
     [self performSelector:@selector(setFoo:value:) withObject:propertyName withObject:argument]; 
    } else { 
     [self performSelector:@selector(foo:) withObject:argument]; 
    } 
} 

- (id)foo:(id)key 
{ 
    return self.properties[key]; 
} 

- (void)setFoo:(id)key value:(id)value 
{ 
    self.properties[key] = value; 
} 

- (id)valueForKey:(NSString *)key 
{ 
    return self.properties[key]; 
} 

- (void)setValue:(id)value forKey:(NSString *)key 
{ 
    self.properties[key] = value; 
} 

我将与清洁器版本以后更新我优化值类型和这样。

0

关于协议的事情是你只向编译器做出承诺,即某个类将实现协议中定义的方法。您需要创建一个实际为方法提供实现的类。协议中定义的属性不是由声明符合协议的类自动合成的,您需要定义底层ivar并为协议中定义的每个属性实现setter和getter以完全符合协议。

换句话说,thingy那里没有得到这些属性是免费的,只是因为它符合协议。

+0

我说OCMock完成了这个。我正在寻找一个不涉及复制整个框架的解决方案。 –

+0

没关系,我告诉你单靠协议无法做到这一点。 –

相关问题