我试图从一个UIViewController中调用UIView中的一个实例方法。在我的UIViewController中,我有这样的东西:
-(void) test {
NSLog(@"test");
}在我的UIViewController中,我创建了一个UIView实例,如下所示:
draggableView = [[DraggableView alloc]initWithFrame:CGRectMake(20, 190, 280, 280)];在我的draggableView中,我想调用test实例方法。如何在不创建UIViewController的新实例的情况下做到这一点?
我有tried this,但它似乎不是一个非常优雅的解决方案,我得到了一个错误"No visible @interface ..."
发布于 2014-07-09 09:48:46
视图没有访问其视图控制器对象的默认方法。您需要自己将视图控制器对象传递到视图对象中。这样做的典型方法是创建一个属性。
@class ViewController;
@interface DraggableView : NSObject
@property (readwrite,nonatomic,assign) ViewController* theOwnerViewController;
@end
@implementation DraggableView
- (void)testCallingOwnerViewControllerMethod
{
[self.theOwnerViewController test];
}
@end您需要在创建theOwnerViewController对象之后设置DraggableView。
- (void)loadView
{
draggableView = [[DraggableView alloc]initWithFrame:CGRectMake(20, 190, 280, 280)];
draggableView.theOwnerViewController = self;
//...extra view setup.
}使用assign避免属性上的保留周期。
委托模式
您可以通过上面的模式来实现这一点,但是正如您注意到的,您需要知道并转发-从它的视图(它是VC的子节点)声明所有者视图控制器类的名称。通常,这是错误的设计选择,因为它很容易产生https://stackoverflow.com/questions/5425465/does-objective-c-allow-circular-dependencies (或向后依赖),这通常会造成紧密耦合。
相反,您可以使用委托模式来避免循环依赖问题。
@protocol TestDelegate
- (void)test;
@end
@interface DraggableView : NSObject
@property(readwrite,nonatomic,assign) id<TestDelegate> testDelegate;
@end
@implementation DraggableView
- (void)test
{
[self.testDelegate test];
}
@end您需要在创建testDelegate对象之后设置DraggableView。
@interface ViewController<TestDelegate>
@end
@implementation
- (void)test
{
// do something.
}
- (void)loadView
{
draggableView = [[DraggableView alloc]initWithFrame:CGRectMake(20, 190, 280, 280)];
draggableView.testDelegate = self;
//...extra view setup.
}
@end在这种情况下,在创建视图对象之前,不必知道它的类名。任何符合TestDelegate协议的类都可以使用,现在视图和VC通过该协议松散耦合。
https://stackoverflow.com/questions/24650263
复制相似问题