我有一个名为产品的UIView,它包含一个名为邮政编码的子UIView。
在邮政编码UIView
中,我有一个简单的表单(一个UITextField
和一个UIButton
)。
当点击UIButton
时,在邮政编码视图中运行一个方法(称为-storeData
)...按预期工作。
现在在storeData
里面我想在superview产品中调用一个方法。
这是我尝试过的,但我收到了警告:
if ([[self superview] class] == [ProductView class]) {
ProductView *p = [self superview];
[p handlePostChange];
}
//从此行ProductView *p = [self superview];
PostView.m:124:28:不兼容的指针类型初始化 'ProductView * __ strong',表达式为'UIView *'
答案 0 :(得分:3)
尝试投射结果:
ProductView *p = (ProductView *)[self superview];
答案 1 :(得分:3)
根据我的评论,可能最好使用委托模式。
我知道除了检查父类的类类型之外,它还有很多代码,但它可以为Product
和Postcode
类分离提供更多功能。因此,实现handlePostChangeFor:
方法的类不再必须是Product
- 只要它实现SuperProtocol
,它就可以是任何类。这反过来意味着您永远不必检查Postocde
内的类类型,因为您不再关心它 - 您关心的是其他一些类可以完成您想要的工作。此外,如果superHandlerDelegate
实例中的Postcode
属性从未设置并保持nil
,您仍然可以,因为Objective-c允许将消息发送到nil
。< / p>
请注意,下面的代码是在非常广泛的笔触中完成的,我留下了很多无关紧要的东西。您的代码和此示例之间的一个主要区别是,您现在必须在handlePostChangeFor:
方法中携带一个参数,以指示您正在处理更改的邮政编码。这是将两个类分离的直接结果。
// Declare a protocol saying "Here is some functionality"
@protocol SuperProtocol
-(void) handlePostChangeFor:(Postcode*)postcode;
@end
// Product class says it will implement the functionality of the SuperProtocol
@interface Product : UIView <SuperProtocol>
@end
@implmementation Product
-(id)init
{
if (!(self=[super init])) return self;
...
// Create/locate the Postcode that is a child of this Product
Postcode* postcode = ... // For example :- [[Postcode alloc] init];
// Tell an instance of the Postcode class who will be supplying the SuperProtocol functionality
postcode.superHandlerDelegate = self;
...
return self;
}
// Implement the protocol's functionality
-(void) handlePostChangeFor:(Postcode*)postcode
{
// Do Stuff with the data from the postcode instance
}
@end
@interface Postcode : UIView
// Identify who will implement the SuperProtocol functionality for this instance
@property (strong, nonatomic) id <SuperProtocol> superHandlerDelegate;
-(IBAction)storeData:(id)sender;
@end
@implementation Postcode
@synthesize superHandlerDelegate;
-(id)init
{
if (!(self=[super init])) return self;
...
// This is not required as NSObject's `alloc` sets everything to all zeroes
// Note that you should not use "self.xxxxx" in an init method
superHandlerDelegate = nil;
...
return self;
}
-(IBAction)storeData:(id)sender
{
...
// Tell the delegate to do the work
[self.superHandlerDelegate handlePostChangeFor:self];
...
}
@end
答案 2 :(得分:2)
对[self superview]
的调用会返回UIView
指针。您正在尝试执行以下操作:
UIView *view;
ProductView *p = view;
编译器无法知道在运行时view
实际上是ProductView
类型。这就是编译器抱怨的原因。
如上所述,解决方案是使用演员:
UIView *view;
ProductView *p = (ProductView *)view;
演员告诉编译器“嘿,别担心,我知道我在做什么。它确实是ProductView
”。当然如果你错了,应用程序很可能会在运行时崩溃。
以下情况非常好:
ProductView *p;
UIView *view = p;
这是安全的,不会发出警告,也不需要演员表。这是有效的,因为已知ProductView
是UIView
的子类。