0

所以我对objective-c还很陌生,我正试图把我的头脑集中在协议上。我将用一个例子来说明我的问题。

假设我有一个执行各种方法的“计算”类。我还有在“计算”中执行相同方法的“Class1”和“Class2”。

现在根据我的理解,我可以使用协议从“计算”访问方法,而无需继承(因此无需在 Class1 和 Class2 中复制相同的代码)。

我的理解也是我必须在 Class1 和 Class2 中实现协议,因此无论如何我都必须输入这些方法。那么协议的意义何在?

我想使用“计算”​​的方法,而不是让它成为 Class1 和 Class2 的超类。所以我开始探索协议,我已经阅读了文档,但我仍然不明白这是如何实现的。如果有人可以用外行的方式解释协议,将不胜感激。

4

5 回答 5

2

继承将使您不必重复代码。协议(其他编程语言称为接口)实现了 OOP 的 Can-Do 结构。这意味着当一个类实现一个协议时,该类表示它可以执行一组特定的方法。仍然由该类来实现他们认为合适的方法。

这是来自 Apple 的开发人员参考:

https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProtocols.html

于 2012-05-29T18:03:18.713 回答
2

协议是一组方法声明。它的主要目的是允许类之间的灵活关系。

假设我希望各种类发送日志消息,但我不希望他们负责知道消息发送后会发生什么。我创建了一个 Logger 协议,然后由 ConsoleWriter 类和 DiskWriter 类实现。想要发送消息的班级不知道也不关心它正在与哪一个对话;它只是与它所知道的东西交谈id<Logger>

于 2012-05-29T18:05:14.317 回答
1

我不知道你有什么类型的语言经验。但是 Object-C 协议非常类似于 .NET 中的接口。它的目的是定义一个契约(接口、封装等),这样就不必知道对象的实际“类型”,而只是知道它可以做什么。

话虽如此,您可以定义一个具有一些属性和方法的协议“MyProtocol.h”。然后你可以在一个类上实现这个协议。您不需要在类的头文件中添加协议的成员,而只需在实现中编写具体的实现。

这样做是允许您通过其定义的接口而不是它们的类型来引用对象。所以你可以使用 id 类型而不是实际的类类型。

希望这可以帮助。

于 2012-05-29T18:03:24.747 回答
1

协议几乎就像一个可移植的头文件。它们描述了可以或应该由任何符合协议的类实现的方法。这与继承不同,在继承中,子类自动实现其超类的方法,并且可以选择在子类的基础上覆盖这些方法。

我怀疑你有一些 OOP 背景,所以我不会过多地讨论子类化,只是说子类通常是超类的专门或更具体的版本。换句话说:每个子类都是其超类的一种,但每个超类不一定是子类的一种。

ObjC 中的协议通常用于委托模式中,其中 ClassA 需要知道 ClassB 可以执行某种操作。这是一个例子:

// ClassA.h
#import "ClassB.h"

@interface ClassA <ClassBProtocol>
// Some variables
@end

// ClassA.m
@implementation ClassA
- (id)init {
    if ( (self = [super init]) ) {
        ClassB *classB = [[ClassB alloc] init]; // Create an instance of ClassB
        classB.delegate = self; // Set ourself as the delegate which means we want ClassB to tell us what to do
    }
    return self;
}

// Introduced by ClassBProtocol
- (void)doSomethingCoolWithString:(NSString *)string {
    // Do something here, it's up to ClassA what to do
}
@end


// ClassB.h
@protocol ClassBProtocol <NSObject>
- (void)doSomethingCoolWithString:(NSString *)string;
@end


@interface ClassB
@property (nonatomic, weak) id <ClassBProtocol>delegate;
// Some variables
@end


//ClassB.m
@implementation ClassB
@synthesize delegate;

- (id)init {
    if ( (self = [super init]) ) {
        if (delegate && [delegate respondsToSelector:@selector(doSomethingCoolWithString:)]) {
            [delegate doSomethingCoolWithString:@"A String"];
        }
    }
    return self;
}
@end
于 2012-05-29T18:08:02.030 回答
-1

下面是简单协议和属性的示例:

---> ViewController.h 文件

#import <UIKit/UIKit.h>
#import "MyVC.h"

@interface ViewController : UIViewController<MyVCProtocol>
{
    IBOutlet UILabel *label;
    IBOutlet UIButton *btnPush;
    MyVC *vc;
}
-(IBAction)Buttonclicked;
@end

---> ViewController.m 文件

#import "ViewController.h"

@implementation ViewController

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

#pragma mark - View lifecycle

- (void)viewDidLoad
{
    [super viewDidLoad];
}

-(IBAction)Buttonclicked
{
    vc = [[MyVC alloc]initWithNibName:@"MyVC" bundle:nil];
    vc.delegate=self;
    [self.navigationController pushViewController:vc animated:YES];
}

-(void)GetText:(NSString *)text
{
    label.textAlignment=UITextAlignmentCenter;
    label.text=text;
}

- (void)viewDidUnload
{
    [super viewDidUnload];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}

@end

---> MyVC.h 文件

#import <UIKit/UIKit.h>

@protocol MyVCProtocol <NSObject>

-(void)GetText:(NSString *)text;

@end

@interface MyVC : UIViewController
{
    IBOutlet UITextField *m_TextField;
    IBOutlet UIButton *m_Button;
    id <MyVCProtocol> delegate;
}
@property(nonatomic, retain)id <MyVCProtocol> delegate;
-(IBAction)ButtonClicked;
@end

---> MyVC.m 文件

#import "MyVC.h"

@implementation MyVC
@synthesize delegate;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

#pragma mark - View lifecycle

- (void)viewDidLoad
{
    [super viewDidLoad];
}

-(IBAction)ButtonClicked
{
    [delegate GetText:m_TextField.text];
    [self.navigationController popViewControllerAnimated:YES];
}

- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    [textField resignFirstResponder];
    return YES;
}

- (void)viewDidUnload
{
    [super viewDidUnload];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

@end
于 2012-05-29T19:34:15.970 回答