iPhone - 访问代理人的财产

时间:2011-03-23 19:08:00

标签: iphone

我有3个班级A,B和C.

B是A的子类。 A有一个名为theView的属性。

我基于B(objectB)创建一个对象。 在objectB里面我创建了一个基于类C的objectC,其中

objectC.delegate = (id)objectB; 
objectB.delegate = (id)objectA;

如何从objectC内部访问objectB的theView属性而无需导入objectB的标头?我想只使用委托属性来做到这一点。

如果我尝试使用C语言,例如:

CGRect bounds = [delegate.theView bounds];

我收到错误:

property theView not found on object of type id<classBdelegate> ???!!!

3 个答案:

答案 0 :(得分:1)

如果不使用属性表示法,则无需导入标题。缺点是你会收到有关未知选择器的警告,当委托对象收到它不理解的选择器时,输入错误会导致运行时崩溃。

CGRect boundsRect = [[delegate theView] bounds];

答案 1 :(得分:1)

您可以使用键/值调用。它们在编译时没有经过类型检查,但会在没有警告的情况下完成工作。如果在运行时获得了错误类型的委托,则调用将返回null,如果它不包含指定的属性(aka .key)。

CGRect bounds = [[[delegate valueForKey:@"theView"] valueForKey:@"bounds"] CGRectValue];

所有这一切,SVD答案的编译时检查会更好IMO。

答案 2 :(得分:1)

要避免出现警告,请创建一个协议,并将其id-typed委托转换为符合该协议的代码,如codelark所示。也就是说,在classC.m中,在@implementation之前:

@protocol ViewHolder
-(UIView*) theView;
@end

然后什么时候调用:

CGRect boundsRect = [[((id<ViewHolder>)delegate) theView] bounds];

这样您就不会正常收到警告,但如果输入错误名称,仍然会收到警告。

P.S。您当然可以在其他地方重用ViewHolder协议定义 - 只需在单独的.h中定义它并根据需要包含它。