Protocoale și accesarea metodelor unei alte clase

Deci, sunt destul de nou la obiectivul-c și încerc să-mi împachet capul în jurul protocoalelor. Voi folosi un exemplu pentru a ilustra întrebarea mea.

Să presupunem că am o clasă "Calculate" care efectuează diferite metode. De asemenea, am "Class1" și "Class2" care efectuează aceleași metode în "Calculate".

Acum, din înțelegerea mea pot folosi protocoale pentru a accesa metode din "Calculați" fără a fi nevoie de moștenire (Prin urmare, salvarea necesității de a replica același cod în Class1 și Class2).

Înțelegerea mea este, de asemenea, că trebuie să pun în aplicare protocoalele din clasa 1 și clasa 2, prin urmare, ar trebui să tip aceste metode oricum. Deci, care este punctul de protocoale?

Vreau să folosesc metodele "Calculați" fără a fi o superclazie a claselor 1 și 2. Așa că am început să explorez protocoalele, am citit documentația, dar încă nu înțeleg cum se realizează acest lucru. Dacă cineva poate explica protocoalele în laic, ar fi apreciat.

0
Sunteți familiarizați cu alte limbi de programare și cu utilizarea interfețelor?
adăugat autor Stefan H, sursa

5 răspunsuri

Moștenirea vă va permite să nu trebuiască să duplicați codul. Protocoalele (ce alte limbi de programare apelează interfețele) implementează o structură Can-Do a OOP. Înseamnă atunci când o clasă implementează un protocol, acea clasă spune că poate face un anumit set de metode. Este totuși obligația acelei clase să pună în aplicare metoda pe care o consideră potrivită.

Iată o referință pentru dezvoltatori de la Apple:

https://developer.apple.com/ bibliotecă/mac/# documentație/cacao/conceptual/ObjectiveC/capitolele/ocProtocols.html

2
adăugat

Un protocol este un set de declarații de metodă. Scopul principal este de a permite relații flexibile între clase.

Let's say I want a variety of classes to send out logging messages but I don't want them responsible for knowing what happens to the messages after they're sent. I create a Logger protocol that is then implemented by a ConsoleWriter class and a DiskWriter class. The class wanting to send the message doesn't know or care which one it's talking to; it just talks to something it knows as id.

2
adăugat

Nu știu cu ce tipuri de limbi aveți experiență. Dar un protocol Object-C seamănă foarte mult cu o interfață în .NET. Scopul este definirea unui contract (interfață, amprentă, etc.) astfel încât "Tipul" real al obiectului să nu fie necesar să fie cunoscut, ci doar ce poate face.

Acestea fiind spuse, puteți defini un protocol "MyProtocol.h" care are câteva proprietăți și metode. Apoi puteți implementa acest protocol pe o clasă. Nu va trebui să adăugați membrii protocolului în antetul clasei, ci pur și simplu trebuie să scrieți implementarea concretă în implementare.

Ceea ce face acest lucru este să vă permiteți să faceți referire la obiect prin interfața definită și nu pe tipul acestora. Deci, puteți utiliza tipul de identificare în locul tipului de clasă reală.

Sper că acest lucru vă ajută.

1
adăugat

Protocoalele sunt aproape ca un fișier cu antet portabil. Acestea descriu metode care pot sau ar trebui să fie implementate de orice clasă care se conformează protocolului. Aceasta este diferită de moștenirea în care o subclasă implementează automat metodele clasei sale superioare, iar aceste metode pot fi înlocuite opțional într-o subclasă bazată pe subclase.

Bănuiesc că aveți o fundație OOP, așa că nu voi merge prea mult în subclasarea decât să spun că o subclasă este foarte des o versiune specializată sau mai specifică a clasei super. Cu alte cuvinte: fiecare subclasă este un fel de superclasă, dar fiecare superclasă nu este neapărat un tip de subclasă.

Protocoalele din ObjC sunt adesea folosite în modelele delegate unde ClassA trebuie să știe că ClassB poate efectua un fel de acțiune. Iată un exemplu:

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

@interface ClassA 
// 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 
- (void)doSomethingCoolWithString:(NSString *)string;
@end


@interface ClassB
@property (nonatomic, weak) id 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
1
adăugat

Below Example for Simple Protocol & Property:

---> ViewController.h File

#import 
#import "MyVC.h"

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

---> ViewController.m File

#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 File

#import 

@protocol MyVCProtocol 

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

@end

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

---> MyVC.m File

#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
1
adăugat