我有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> ???!!!
答案 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中定义它并根据需要包含它。