我在Objective-C中创建了一个多播委托,它拦截了一条消息,然后通过迭代forwardInvocation
中的子节点列表将它转发给多个子节点。复杂程度要高得多,但我不认为这与问题/问题有关。
- (void)forwardInvocation:(NSInvocation *)anInvocation
{
for (id child in self.children)
{
if ([child respondsToSelector:[anInvocation selector]])
{
[anInvocation invokeWithTarget:child];
}
}
}
这对于具有void
返回类型的协议完全有意义,但如果它们返回值会发生什么?
我看到了这个问题,并编写了以下单元测试,该测试通过:
static NSUInteger _callCounter = 0;
@protocol TestProtocol <NSObject>
- (NSUInteger)requiredMethod;
@end
@interface TestClass : NSObject <TestProtocol>
@end
@implementation TestClass
- (NSUInteger)requiredMethod
{
return ++_callCounter;
}
@end
␠
- (void)testCallerOrder
{
_callCounter = 0;
ProtococolMulticaster *multicaster = [[ProtococolMulticaster alloc] initWithProtocol:@protocol(TestProtocol)];
//As the multicaster holds weak references, we need to retain the children
NS_VALID_UNTIL_END_OF_SCOPE NSMutableArray *childReferences = [NSMutableArray array];
for (int i = 0; i < 3; i++)
{
id child = [TestClass new];
[childReferences addObject:child];
[multicaster addChild:child];
}
XCTAssertEqual([(id<TestProtocol>)multicaster requiredMethod], 3);
}
这里的期望是3个孩子都被调用,我的静态增加3次然后由阵列中的最后一个孩子返回给我。因为这个过去了,我的结论是它是被调用的最后一个forwardInvocation,它给出了[(id<TestProtocol>)multicaster requiredMethod]
的返回值。
这个假设是否正确?任何人都可以准确地解释这里发生了什么?是否有任何我可能错过的边缘情况可能导致这种不可预测的情况?