I have a UIView called Product , which contains a sub UIView called Postcode .
In the Postcode UIView
i have a simple form (one UITextField
and one UIButton
).
When the UIButton
is clicked a method (called -storeData
) is run inside postcode view ... which works as intended.
Now inside storeData
I would like to call a method in the superview Product.
This is what i tried doing, but im getting a warning:
if ([[self superview] class] == [ProductView class]) {
ProductView *p = [self superview];
[p handlePostChange];
}
// Get this warning from this line ProductView *p = [self superview];
PostView.m:124:28: Incompatible pointer types initializing 'ProductView *__strong' with an expression of type 'UIView *'
尝试仅投射结果:
ProductView *p = (ProductView *)[self superview];
As per my comment you may be better off using a delegation pattern.
I know it is a lot more code than simply checking the class type of the parent, but it gains you a lot more capability as it decouples the Product
and Postcode
classes. Thus the class that implements the handlePostChangeFor:
method no longer has to be Product
- it can be any class as long as it implements the SuperProtocol
. Which in turn means you never have to check the class type inside Postocde
, as you no longer care about it - all you care about is that some other class can do the work you want. Also if the superHandlerDelegate
property in the instance of a Postcode
is never set and remains nil
you are still OK as Objective-c allows messages to be sent to nil
.
Note that the code below is done in very broad brushstrokes and I have left a lot of extraneous stuff out. One main difference between your code and this example is that you now have to carry a parameter in the handlePostChangeFor:
method to indicate which Postcode you are handling the change for. This is a direct result of having decoupled the two classes.
// 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
The call to [self superview]
returns a UIView
pointer. You are trying to do the equivalent of:
UIView *view;
ProductView *p = view;
The compiler has no way to know that at runtime, view
will really be of type ProductView
. This is why the compiler complains.
The solution, as was stated, is to use a cast:
UIView *view;
ProductView *p = (ProductView *)view;
The cast tells the compiler "hey, don't worry, I know what I'm doing. It really is a ProductView
". Of course if you are wrong, the app will most likely crash at runtime.
The following is perfectly fine:
ProductView *p;
UIView *view = p;
This is safe, gives no warning, and requires no cast. This works because it is known that ProductView
is a subclass of UIView
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.