Ios 从视图调用ViewController中的实例方法
我试图从UIView中调用UIViewController中的实例方法。在我的UIViewController中,我有如下内容:Ios 从视图调用ViewController中的实例方法,ios,objective-c,Ios,Objective C,我试图从UIView中调用UIViewController中的实例方法。在我的UIViewController中,我有如下内容: -(void) test { NSLog(@"test"); } 在我的UIViewController中,我创建了一个UIView实例,如下所示: draggableView = [[DraggableView alloc]initWithFrame:CGRectMake(20, 190, 280, 280)]; 在我的draggableView中,我想
-(void) test {
NSLog(@"test");
}
在我的UIViewController中,我创建了一个UIView实例,如下所示:
draggableView = [[DraggableView alloc]initWithFrame:CGRectMake(20, 190, 280, 280)];
在我的draggableView
中,我想调用test
实例方法。如何在不创建UIViewController的新实例的情况下执行此操作
我有,但这似乎不是一个非常优雅的解决方案,我得到了一个错误
“No visible@interface…”
视图没有访问其视图控制器对象的默认方法。
您需要自己将视图控制器对象传递到视图对象中。
实现这一点的典型方法是创建一个属性
@class ViewController;
@interface DraggableView : NSObject
@property (readwrite,nonatomic,assign) ViewController* theOwnerViewController;
@end
@implementation DraggableView
- (void)testCallingOwnerViewControllerMethod
{
[self.theOwnerViewController test];
}
@end
创建DraggableView
对象后,需要设置所有者视图控制器
- (void)loadView
{
draggableView = [[DraggableView alloc]initWithFrame:CGRectMake(20, 190, 280, 280)];
draggableView.theOwnerViewController = self;
//...extra view setup.
}
@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
使用assign
避免在属性上保留循环
@class ViewController;
@interface DraggableView : NSObject
@property (readwrite,nonatomic,assign) ViewController* theOwnerViewController;
@end
@implementation DraggableView
- (void)testCallingOwnerViewControllerMethod
{
[self.theOwnerViewController test];
}
@end
委托模式
您可以通过上面的模式实现这一点,但正如您所注意到的,您需要知道并从其视图(VC的子节点)中转发声明所有者视图控制器类的名称。通常这是一个糟糕的设计选择,因为它很容易产生(或向后依赖),这通常会产生紧密耦合
相反,您可以使用委托模式来避免循环依赖性问题
@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
协议的类都可以使用,现在视图和VC通过协议松散耦合。使用委托(即告诉视图控制器委托使用视图,并对该委托进行视图调用)。感谢@特洛伊木马,你有好的例子吗?代表在Objective-C中非常常见,网上有大量的例子和问题。例如:谢谢,我会检查它的。我之前确实尝试过,但我一直收到错误不可见@interface声明选择器测试@eskimo您可以通过在使用前声明@class
名称来避免错误。无论如何,委托提供了更多的灵活性和更少的依赖性。谢谢@Eonil。你这么说(声明类名)是什么意思?循环依赖性问题很容易解决。让视图了解视图控制器的缺点是:增加了两个类之间的耦合;在另一个上下文中重用视图变得不可能;它还使视图能够控制其控制器,这将使控制流难以跟随。@eskimo,具体意思是@class ViewController代码>行。有关更多详细信息,请参阅。