Как использовать делегата в задаче C и Swift Viewcontroller

Мой проект объединен с одним контроллером представления, написанным на объектном C (objCViewController), а другой написан с помощью swift (SwiftViewCOntroller). У меня есть несколько переменных NSString. Я хотел бы обновить строку в objCViewController и получить к ней доступ в SwiftViewController с помощью делегата, потому что мне нужно постоянно переключаться между этими двумя контроллерами представления и постоянно обновлять строку.

Вот код:

objCViewController.h

#import <UIKit/UIKit.h>

@protocol MyDelegate <NSObject>
@end

@interface objCViewController : UIViewController{
  NSString * stringbeingpassed;
}

@property (nonatomic, weak) id<MyDelegate> delegate;
@property (nonatomic, retain) NSString * stringbeingpassed;
@end

objCViewController.m

@implementation objCViewController
@synthesize delegate;
@synthesize stringbeingpassed;

- (void)updatestring {
  //update string in this method
  NSString * newstring = @"testing";

  if (delegate != nil && [delegate respondsToSelector:@selector(stringUpdated:)]) {
    [delegate stringUpdated: newstring];
}

}

заголовок заголовка.h:

#import "objCViewController.h"

SwiftViewController.swift:

protocol MyDelegate {
func stringUpdated(newMessage: String)
}

import UIKit
@objc class SwiftViewController: UIViewController, MyDelegate{
override func viewDidLoad() {
    super.viewDidLoad()
}

func stringUpdated(newMessage:String) {
let newMessage = "sent string"
}

Я пытался использовать делегат, но я понятия не имею, как его использовать. Я совершенно новичок в быстром и объективном C

Q1. Я хотел бы спросить, как я могу назначить мою новую строку для делегирования в objCViewController, а затем передать ее в SwiftViewController.

Q2. Другой вопрос заключается в том, как я могу получить данные в делегате в SwiftViewController. Что мне добавить?

Q3. Что-нибудь еще, что я пропустил при определении делегата? Нужно ли мне определять его в обоих контроллерах просмотра? Спасибо.


person Hugo.W    schedule 09.04.2018    source источник


Ответы (2)


Трудно сказать, является ли делегат подходящим инструментом для работы, из-за минимальной предоставленной информации. На самом деле я мог бы предложить изучить лучшие способы разработки вашего приложения.

При этом было бы полезно увидеть код для вашего протокола MyDelegate. Если этого протокола еще нет, ему понадобится «func», который принимает «String» в качестве аргумента/параметра. А пока давайте назовем эту функцию stringUpdated. С помощью предоставленного кода вам потребуется установить экземпляр SwiftViewController для вашего свойства delegate в objCViewController. Таким образом, когда вызывается updatestring, вы можете сделать что-то вроде этого:

- (void)updatestring {
    //update string in this method
    NSString * newstring = @"testing";

    if (delegate != nil && [delegate respondsToSelector:@selector(stringUpdated:)]) {
        [delegate stringUpdated: newstring]
    }
}

В SwiftViewController вам придется принять такой протокол:

@objc class SwiftViewController: UIViewController, MyDelegate {

а затем придерживаться протокола, реализуя функцию stringUpdated.

Обновить

В вашем протоколе по-прежнему отсутствует метод. Это должно выглядеть так:

@protocol MyDelegate
- (void) stringUpdated:(NSString *)updatedString;
@end
person Taylor2412    schedule 09.04.2018
comment
Я создал func stringUpdated в SwiftViewController Вот код: протокол MyDelegate { func stringUpdated (newMessage: message)} func stringUpdated (newMessage: String) { newMessage = отправленная строка}, но в objCViewController я получил ошибки: нет известного метода экземпляра для селектора 'respondsToSelector:' Нет известного метода экземпляра для селектора 'stringUpdated:' - person Hugo.W; 09.04.2018
comment
Не могли бы вы отредактировать/обновить свой вопрос в своем протоколе, пожалуйста? Похоже, что протокол был определен в swift и не соответствует NSObject, который должен быть для работы с Obj-C. - person Taylor2412; 09.04.2018
comment
вопрос обновлен. Я добавил ‹NSObject› в протокол Mydelegate, и теперь у меня все еще есть ошибка в objCViewController: нет известного метода экземпляра для селектора 'stringUpdated:' - person Hugo.W; 09.04.2018
comment
Ой, извините, я не увидел ваш протокол вверху заголовка objCViewController. Вы пропустили очень важную часть, и это фактическая причина, по которой он возвращает эту ошибку. Вы никогда не определяли метод протокола, как я описал выше. Я добавил пример в свой ответ. - person Taylor2412; 09.04.2018
comment
В чем смысл этого оператора if? if (делегат != nil && [делегат responsesToSelector:@selector(stringUpdated:)]) . Мой код не может работать с этим оператором if, и мне не удалось выполнить printf внутри этого оператора if. - person Hugo.W; 10.04.2018
comment
Он проверяет, установили ли вы делегат и реализовал ли делегат метод stringUpdated. Причина, по которой вы не попадаете внутрь, заключается в том, что вы не добавили метод как часть протокола, и я не вижу, чтобы вы устанавливали свой делегат на экземпляр SwiftViewController. Я настоятельно рекомендую просмотреть некоторые учебные пособия или убедиться, что это лучший способ справиться с тем, что вы пытаетесь сделать, поскольку кажется, что вы не понимаете большую часть того, что я пытаюсь передать. - person Taylor2412; 10.04.2018

позвольте мне сначала ответить на Q3 Q3: Что-нибудь еще, что я пропустил при определении делегата? Нужно ли определять его в обоих контроллерах представления? Нет, вам не нужно определять MyDelegate в обоих контроллерах представления, просто добавьте его в objCViewControlle.

Теперь здесь, я изменил ваш код

objCViewController.h

@protocol MyDelegate <NSObject>
- (void) stringUpdated:(NSString *)updatedString;
- (NSString *) getString;
@end

@interface objCViewController : UIViewController{
  NSString * stringbeingpassed;
}

@property (nonatomic, weak) id<MyDelegate> delegate;
@property (nonatomic, retain) NSString * stringbeingpassed;
@end

заголовок заголовка.h:

#import "objCViewController.h"

SwiftViewController.swift:

import UIKit
@objc class SwiftViewController: UIViewController, MyDelegate{
var thisIsObjectiveVCString:String?
override func viewDidLoad() {
    super.viewDidLoad()
}

func stringUpdated(newMessage:String) {
thisIsObjectiveVCString = newMessage
}

func getString() ->String {
return thisIsObjectiveVCString
}
}

Вопрос 2. Как получить данные делегата в SwiftViewController. Что добавить?

на objCViewControlle

if (delegate != nil && [delegate respondsToSelector:@selector(getString)]) {
        NSString * theString = [delegate getString];
    }

Вопрос 1: как я могу назначить строку новостей для делегирования в objCViewController, а затем передать ее в SwiftViewController

фактически на objCViewController, если вы вызовете updatestring, вы обновите SwiftViewController

person Same7Farouk    schedule 17.04.2018