Ios 从视图调用ViewController中的实例方法

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中,我想

我试图从UIView中调用UIViewController中的实例方法。在我的UIViewController中,我有如下内容:

-(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行。有关更多详细信息,请参阅。