1

我有一个名为Product的 UIView ,其中包含一个名为Postcode的子 UIView 。

在邮政编码中,UIView我有一个简单的表格(一个UITextField和一个UIButton)。

单击时,将在邮政编码视图中运行UIButton一个方法(称为)...按预期工作。-storeData

现在在里面storeData我想调用superview Product中的一个方法。

这是我尝试做的,但我收到警告:

if ([[self superview] class] == [ProductView class]) {
        ProductView *p = [self superview]; 
        [p handlePostChange]; 
    }

// 从此行获取此警告ProductView *p = [self superview];

PostView.m:124:28:使用“UIView *”类型的表达式初始化“ProductView *__strong”的不兼容指针类型

4

3 回答 3

3

尝试只投射结果:

ProductView *p = (ProductView *)[self superview];
于 2012-12-09T23:47:42.867 回答
3

根据我的评论,您最好使用委托模式。

我知道它比简单地检查父类的类类型要多得多的代码,但它使你获得了更多的能力,因为它解耦了ProductPostcode类。因此,实现该handlePostChangeFor:方法的类不再必须是Product- 它可以是任何类,只要它实现了SuperProtocol. 这反过来意味着你永远不必检查里面的类类型Postocde,因为你不再关心它——你关心的是其他类可以做你想做的工作。此外,如果superHandlerDelegatea 实例中的属性Postcode从未设置并且仍然存在nil,那么您仍然可以,因为 Objective-c 允许将消息发送到nil.

请注意,下面的代码是用非常广泛的笔触完成的,我遗漏了很多无关的东西。您的代码与此示例之间的一个主要区别是您现在必须在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
于 2012-12-10T12:09:52.967 回答
2

调用[self superview]返回一个UIView指针。您正在尝试执行以下操作:

UIView *view;
ProductView *p = view;

编译器无法知道在运行时,view是否真的是 type ProductView。这就是编译器抱怨的原因。

如前所述,解决方案是使用演员表:

UIView *view;
ProductView *p = (ProductView *)view;

演员告诉编译器“嘿,别担心,我知道我在做什么。它真的是一个ProductView”。当然,如果你错了,应用程序很可能会在运行时崩溃。

以下是完全没问题的:

ProductView *p;
UIView *view = p;

这是安全的,不会发出警告,也不需要强制转换。这是有效的,因为已知它ProductView是 的子类UIView

于 2012-12-10T00:02:21.247 回答