Objective-C에서 딜러를 작성하려면 어떻게 해야 합니까?
저는 대표자들이 어떻게 일하는지 알고 있고, 어떻게 그들을 사용할 수 있는지 알고 있습니다.
그럼 어떻게 만들까요?
은 Objective-C에 입니다.delegate
하다이를 만들려면 원하는 위임 메서드를 구현하는 클래스를 정의하고 해당 클래스를 위임 프로토콜 구현으로 표시합니다.
를 들어,를 들면, '아까다', '아까다', '다'가 있다고 합시다.UIWebView
대리자의 메서드를 구현하려면 다음과 같은 클래스를 만들 수 있습니다.
@interface MyClass<UIWebViewDelegate>
// ...
@end
@implementation MyClass
- (void)webViewDidStartLoad:(UIWebView *)webView {
// ...
}
@end
그런 다음 MyClass 인스턴스를 만들어 웹 보기의 위임자로 할당할 수 있습니다.
MyClass *instanceOfMyClass = [[MyClass alloc] init];
myWebView.delegate = instanceOfMyClass;
에에 。UIWebView
하는지 확인하기 한 코드를 수 .webViewDidStartLoad:
메시지를 사용하고 필요에 따라 발송합니다.
if([self.delegate respondsToSelector:@selector(webViewDidStartLoad:)]) {
[self.delegate webViewDidStartLoad:self];
}
는 일반적으로 "Delegate Property"weak
) 또는 (ARC의 경우)assign
(Pre-ARC) 오브젝트의 위임자가 그 오브젝트에 대한 강한 참조를 가지고 있는 경우가 많기 때문에 루프를 유지하는 것을 피하기 위해 (예를 들어 뷰 컨트롤러는 대부분의 경우 포함된 뷰의 위임자)
강의에 참가하기 위한 딜러 만들기
대리인을 정의하려면 프로토콜에 대한 Apple Docs에서 설명한 대로 대리인의 메서드를 선언해야 합니다.당신은 보통 정식 프로토콜을 선언합니다.선언은 UI WebView.h에서 바꿔 말하면 다음과 같습니다.
@protocol UIWebViewDelegate <NSObject>
@optional
- (void)webViewDidStartLoad:(UIWebView *)webView;
// ... other methods here
@end
클래스와 하며, 인 "Displicthe abstract base class" 。UIWebViewDelegate
프로토콜을 .위임 구현자는 다음 프로토콜을 채택해야 합니다.
@interface MyClass <UIWebViewDelegate>
// ...
@end
그리고 프로토콜에 메서드를 구현합니다.:@optional
의 위임방법과 로) ('대부분의 위임방식에 .-respondsToSelector:
특정 메서드를 호출하기 전에 이 메서드를 호출합니다.
명명
위임 메서드는 일반적으로 위임 클래스 이름부터 시작하여 이름이 지정되며 위임 개체를 첫 번째 매개 변수로 사용합니다.그들은 또한 종종 유언장, 해야 할 것, 또는 실행한 것을 사용한다.so,는,webViewDidStartLoad:
뷰가 loadStarted
예를 들어 (매개변수를 사용하지 않음)입니다.
속도 최적화
메시지를 보낼 때마다 대리인이 셀렉터에 응답하는지 여부를 확인하는 대신 대리인이 설정될 때 해당 정보를 캐시할 수 있습니다.이를 위한 매우 깨끗한 방법 중 하나는 다음과 같이 비트필드를 사용하는 것입니다.
@protocol SomethingDelegate <NSObject>
@optional
- (void)something:(id)something didFinishLoadingItem:(id)item;
- (void)something:(id)something didFailWithError:(NSError *)error;
@end
@interface Something : NSObject
@property (nonatomic, weak) id <SomethingDelegate> delegate;
@end
@implementation Something {
struct {
unsigned int didFinishLoadingItem:1;
unsigned int didFailWithError:1;
} delegateRespondsTo;
}
@synthesize delegate;
- (void)setDelegate:(id <SomethingDelegate>)aDelegate {
if (delegate != aDelegate) {
delegate = aDelegate;
delegateRespondsTo.didFinishLoadingItem = [delegate respondsToSelector:@selector(something:didFinishLoadingItem:)];
delegateRespondsTo.didFailWithError = [delegate respondsToSelector:@selector(something:didFailWithError:)];
}
}
@end
다음 대리인이 할 수 .delegateRespondsTo
structure를 송신하는 것이 「」를 으로 합니다.-respondsToSelector:
반복해서.
비공식 대표자
프로토콜이 존재하기 전에는 일반적으로 다음과 같은 카테고리를 사용했습니다.NSObject
위임자가 구현할 수 있는 방법을 선언합니다.를 들어, 「」라고 하는 것은,CALayer
도 이렇게 있어요, 하다, 하다, 하다, 하다, 하다.
@interface NSObject(CALayerDelegate)
- (void)displayLayer:(CALayer *)layer;
// ... other methods here
@end
라도 '실장'할 수 을 알 수 .displayLayer:
.
같은 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아,-respondsToSelector:
이 메서드를 호출하기 위해 위에서 설명한 대로 접근합니다.는 이 하고 " "를 합니다.delegate
(프로토콜을 준수한다고 선언할 수 없습니다.)라이브러리에서 으로 사용되고 에서는 위의 현대적인 해야 합니다.이을 일으키기 입니다. 왜냐하면 이 접근법이 오염을 일으키기 때문입니다.NSObject
(오타 및 유사한 오류에 대해 컴파일러가 경고하는 것을 어렵게 합니다).
승인된 답변은 훌륭하지만, 1분간의 답변을 원하는 경우 다음을 참조하십시오.
MyClass.h 파일은 다음과 같습니다(댓글이 있는 대리자 행 추가).
#import <BlaClass/BlaClass.h>
@class MyClass; //define class, so protocol can see MyClass
@protocol MyClassDelegate <NSObject> //define delegate protocol
- (void) myClassDelegateMethod: (MyClass *) sender; //define delegate method to be implemented within another class
@end //end protocol
@interface MyClass : NSObject {
}
@property (nonatomic, weak) id <MyClassDelegate> delegate; //define MyClassDelegate as delegate
@end
MyClass.m 파일은 다음과 같습니다.
#import "MyClass.h"
@implementation MyClass
@synthesize delegate; //synthesise MyClassDelegate delegate
- (void) myMethodToDoStuff {
[self.delegate myClassDelegateMethod:self]; //this will call the method implemented in your other class
}
@end
다른 클래스(이 경우 MyVC라는 이름의 UIViewController)에서 대리인을 사용하려면 다음 절차를 수행합니다.
#import "MyClass.h"
@interface MyVC:UIViewController <MyClassDelegate> { //make it a delegate for MyClassDelegate
}
MyVC.m:
myClass.delegate = self; //set its delegate to self somewhere
위임 방식 구현
- (void) myClassDelegateMethod: (MyClass *) sender {
NSLog(@"Delegates are great!");
}
위임 지원을 작성하기 위해 정식 프로토콜 방법을 사용할 때 다음과 같은 사항을 추가하여 적절한 유형 검사(비록 런타임, 컴파일 시간이 아님)를 보장할 수 있습니다.
if (![delegate conformsToProtocol:@protocol(MyDelegate)]) {
[NSException raise:@"MyDelegate Exception"
format:@"Parameter does not conform to MyDelegate protocol at line %d", (int)__LINE__];
}
(setDelegate) 코드를 입력합니다.이를 통해 실수를 최소화할 수 있습니다.
아마 이것은 당신이 놓치고 있는 것과 비슷할 것입니다.
C++와 같은 관점에서 온 경우, 딜러들은 조금 익숙해지는데 시간이 걸리지만 기본적으로는 '일만 할 뿐'입니다.
NSWindow에 위임자로 쓴 일부 개체를 설정하지만 개체에는 여러 위임 메서드 중 하나 또는 몇 가지에 대한 구현(메서드)만 있습니다. 무슨 래서 so so so so so so so so so so so so so so, 리 so so so so so?NSWindow
.객관적-c의 '오브젝티브-c합니다.오브젝티브-c만 사용합니다.respondsToSelector
가 그 호출하고 입니다.이것이 objective-c의 작동 방식입니다. 즉, 필요에 따라 메서드를 검색합니다.
것은 , , '자기 물건으로 하는 것', '자기 물건으로 하는 것', '자기 물건으로 하는 것', ' 물건으로 하는 거 있잖아요.예예 、 를를 、 ,를 、NSArray
종류의사물 에서, 만이 27개의 다른 을 가지고 있다.-(void)setToBue;
에 콜을 하기 setToBlue
필요한 18개 모두에 대해 다음과 같은 정보를 제공합니다.
for (id anObject in myArray)
{
if ([anObject respondsToSelector:@selector(@"setToBlue")])
[anObject setToBlue];
}
또를 '유지하다'로 것입니다.nil
안에서MyClass dealloc
★★★★★★ 。
아래의 간단한 단계별 튜토리얼을 확인하여 딜러가 iOS에서 어떻게 작동하는지 이해하십시오.
2개의 View Controller(데이터를 1개에서 다른 것으로 송신하기 위한)를 작성했습니다.
- FirstViewController 구현 위임(데이터 제공)
- SecondViewController가 위임(데이터를 수신함)을 선언합니다.
애플이 권장하는 모범 사례로서 대표자(정의상 프로토콜)는 다음을 준수하는 것이 좋습니다.NSObject
프로토콜입니다.
@protocol MyDelegate <NSObject>
...
@end
를하여 대리자 반드시 할 필요가 )를 할 수 .@optional
을 붙입니다
@protocol MyDelegate <NSObject>
...
...
// Declaration for Methods that 'must' be implemented'
...
...
@optional
...
// Declaration for Methods that 'need not necessarily' be implemented by the class conforming to your delegate
...
@end
는 ( respondsToSelector
(위임자에게 적합한) 뷰가 옵션 메서드를 실제로 구현했는지 여부를 확인합니다.
일단 대표자를 이해하면 이 모든 답변이 타당하다고 생각합니다.개인적으로 저는 C/C++의 나라에서 왔고, 그 전에 Fortran 등의 절차적 언어에서 왔기 때문에 C++ 패러다임에서 유사한 유사점을 찾는 것에 대한 저의 2분간의 견해가 있습니다.
C++/Java 프로그래머에게 딜러에 대해 설명하면 다음과 같습니다.
딜러란 무엇입니까?이들은 다른 클래스 내의 클래스에 대한 정적 포인터입니다.포인터를 할당하면 해당 클래스의 함수/메서드를 호출할 수 있습니다.따라서 클래스의 일부 함수는 다른 클래스로 "위임"됩니다(C++ 월드에서는 클래스 객체 포인터에 의한 포인터).
프로토콜이란 무엇입니까?개념적으로는 위임 클래스로 할당하는 클래스의 헤더 파일과 유사한 목적으로 기능합니다.프로토콜은 클래스 내에서 포인터를 위임자로 설정한 클래스에서 구현해야 하는 메서드를 정의하는 명시적인 방법입니다.
어떻게 하면 C++에서 비슷한 걸 할 수 있을까요?이를 C++에서 실행하려고 하면 클래스 정의에서 클래스(개체)에 대한 포인터를 정의한 후 기본 클래스에 위임으로 추가 함수를 제공하는 다른 클래스에 연결합니다.단, 이 배선은 코드 내에서 유지되어야 하며 서툴고 오류가 발생하기 쉽습니다.목표 C는 프로그래머가 이 decipliine을 유지하는 데 능숙하지 않다고 가정하고 컴파일러 제한을 제공하여 클린 구현을 강제합니다.
스위프트 버전
대표자는 다른 반에서 일을 하는 반일 뿐이다.다음 코드를 읽고 Swift에서 이 작업을 수행하는 방법을 보여주는 다소 바보 같은(그러나 희망적으로 계몽적인) Playground의 예를 들어보십시오.
// A protocol is just a list of methods (and/or properties) that must
// be used by any class that adopts the protocol.
protocol OlderSiblingDelegate: class {
// This protocol only defines one required method
func getYourNiceOlderSiblingAGlassOfWater() -> String
}
class BossyBigBrother {
// The delegate is the BossyBigBrother's slave. This position can
// be assigned later to whoever is available (and conforms to the
// protocol).
weak var delegate: OlderSiblingDelegate?
func tellSomebodyToGetMeSomeWater() -> String? {
// The delegate is optional because there might not be anyone
// nearby to boss around.
return delegate?.getYourNiceOlderSiblingAGlassOfWater()
}
}
// PoorLittleSister conforms to the OlderSiblingDelegate protocol
class PoorLittleSister: OlderSiblingDelegate {
// This method is repquired by the protocol, but the protocol said
// nothing about how it needs to be implemented.
func getYourNiceOlderSiblingAGlassOfWater() -> String {
return "Go get it yourself!"
}
}
// initialize the classes
let bigBro = BossyBigBrother()
let lilSis = PoorLittleSister()
// Set the delegate
// bigBro could boss around anyone who conforms to the
// OlderSiblingDelegate protocol, but since lilSis is here,
// she is the unlucky choice.
bigBro.delegate = lilSis
// Because the delegate is set, there is a class to do bigBro's work for him.
// bigBro tells lilSis to get him some water.
if let replyFromLilSis = bigBro.tellSomebodyToGetMeSomeWater() {
print(replyFromLilSis) // "Go get it yourself!"
}
실제로 딜러는 다음과 같은 상황에서 자주 사용됩니다.
- 클래스가 일부 정보를 다른 클래스에 전달할 필요가 있는 경우
- 클래스에서 다른 클래스가 사용자 정의할 수 있도록 허용하려는 경우
위임 클래스가 필요한 프로토콜을 준수한다는 점을 제외하고 클래스는 서로에 대해 미리 알 필요가 없습니다.
나는 다음 두 기사를 읽을 것을 강력히 추천한다.그들은 내가 대표자들을 문서보다 더 잘 이해할 수 있도록 도와주었다.
좋아요, 이건 질문에 대한 답은 아니지만, 만약 당신이 당신 자신의 대리인을 만드는 방법을 찾고 있다면, 아마도 훨씬 더 간단한 것이 당신에게 더 나은 답이 될 수 있을 거예요.
나는 거의 필요하지 않기 때문에 나의 대표자들을 거의 실행하지 않는다.위임 개체에 대해 위임자를 하나만 가질 수 있습니다.따라서 통지보다 일방적인 커뮤니케이션/데이터 전달을 위해 대리인을 필요로 하는 경우.
NSNotification은 여러 수신자에게 개체를 전달할 수 있으며 매우 사용하기 쉽습니다.다음과 같이 동작합니다.
MyClass.m 파일은 다음과 같습니다.
#import "MyClass.h"
@implementation MyClass
- (void) myMethodToDoStuff {
//this will post a notification with myClassData (NSArray in this case) in its userInfo dict and self as an object
[[NSNotificationCenter defaultCenter] postNotificationName:@"myClassUpdatedData"
object:self
userInfo:[NSDictionary dictionaryWithObject:selectedLocation[@"myClassData"] forKey:@"myClassData"]];
}
@end
다른 클래스에서 알림을 사용하려면:클래스를 옵서버로 추가합니다.
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(otherClassUpdatedItsData:) name:@"myClassUpdatedData" object:nil];
실렉터를 실장합니다.
- (void) otherClassUpdatedItsData:(NSNotification *)note {
NSLog(@"*** Other class updated its data ***");
MyClass *otherClass = [note object]; //the object itself, you can call back any selector if you want
NSArray *otherClassData = [note userInfo][@"myClassData"]; //get myClass data object and do whatever you want with it
}
옵저버로서 수업을 빼는 것을 잊지 마세요.
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
작성한 클래스가 있으며 이벤트가 발생했을 때 이를 통지할 수 있도록 위임 속성을 선언한다고 가정합니다.
@class myClass;
@protocol myClassDelegate <NSObject>
-(void)myClass:(MyClass*)myObject requiredEventHandlerWithParameter:(ParamType*)param;
@optional
-(void)myClass:(MyClass*)myObject optionalEventHandlerWithParameter:(ParamType*)param;
@end
@interface MyClass : NSObject
@property(nonatomic,weak)id< MyClassDelegate> delegate;
@end
, ''을 합니다.MyClass
file 파일)및한 후 파일(「」)의 합니다.MyClass
의 타입type 。id< MyClassDelegate>
는를 의미합니다.MyClassDelegate
weak로 수 유지 사이클을 매우 는 "heak"을이것은 유지 사이클을 방지하기 위해 매우 중요합니다(대부분 딜러가 유지).MyClass
따라서 대리인을 유지로 선언한 경우 둘 다 서로를 유지하며 둘 다 해제되지 않습니다).
으로는 '의례적인 방법'이 '의례적인 방법'이 '의례적인 방법'으로 넘어간다는 을 알 수 .MyClass
parameter.가 instance의 입니다.이것은 위임자가 몇 가지 메서드를 호출하는 경우의 베스트 프랙티스입니다.MyClass
및 .MyClassDelegate
개로MyClass
를 들어 여러 개의 "" " " " " " 경우UITableView's
의 ViewController
을 「」라고 합니다.UITableViewDelegate
모두에게요.
그 에.MyClass
if([_delegate respondsToSelector:@selector(myClass: requiredEventHandlerWithParameter:)])
{
[_delegate myClass:self requiredEventHandlerWithParameter:(ParamType*)param];
}
먼저 위임자가 호출하려는 프로토콜 메서드에 응답하는지 여부를 확인합니다. 위임자가 프로토콜 메서드를 구현하지 않으면 앱이 충돌합니다(프로토콜 메서드가 필요하더라도).
자신의 대리인을 작성하려면 먼저 프로토콜을 작성하고 구현하지 않고 필요한 메서드를 선언해야 합니다.그런 다음 위임 또는 위임 메서드를 구현할 헤더 클래스에 이 프로토콜을 구현하십시오.
프로토콜은 다음과 같이 선언해야 합니다.
@protocol ServiceResponceDelegate <NSObject>
- (void) serviceDidFailWithRequestType:(NSString*)error;
- (void) serviceDidFinishedSucessfully:(NSString*)success;
@end
이것은 몇 가지 작업을 수행해야 하는 서비스 클래스입니다.대리인을 정의하는 방법과 대리인을 설정하는 방법을 보여 줍니다.태스크 완료 후 구현 클래스에서는 딜러가 메서드를 호출합니다.
@interface ServiceClass : NSObject
{
id <ServiceResponceDelegate> _delegate;
}
- (void) setDelegate:(id)delegate;
- (void) someTask;
@end
@implementation ServiceClass
- (void) setDelegate:(id)delegate
{
_delegate = delegate;
}
- (void) someTask
{
/*
perform task
*/
if (!success)
{
[_delegate serviceDidFailWithRequestType:@”task failed”];
}
else
{
[_delegate serviceDidFinishedSucessfully:@”task success”];
}
}
@end
이 클래스는 서비스 클래스를 호출하는 기본 뷰 클래스입니다.이 클래스는 대리자를 직접 설정합니다.또한 프로토콜은 헤더 클래스에서 구현됩니다.
@interface viewController: UIViewController <ServiceResponceDelegate>
{
ServiceClass* _service;
}
- (void) go;
@end
@implementation viewController
//
//some methods
//
- (void) go
{
_service = [[ServiceClass alloc] init];
[_service setDelegate:self];
[_service someTask];
}
이상입니다. 이 클래스에서 위임 메서드를 구현함으로써 작업/태스크가 완료되면 제어가 다시 시작됩니다.
대리인을 작성하는 간단한 방법은 다음과 같습니다.
파일에 .h 파일에 프로토콜을 만듭니다.에 @후을 @class로 합니다.< As the protocol I am going to use is UIViewController class>.
스텝 : 1 : UIViewController 클래스의 서브클래스가 되는 "YourViewController"라는 이름의 새 클래스 프로토콜을 만들고 이 클래스를 두 번째 ViewController에 할당합니다.
순서 : 2 : "YourViewController" 파일로 이동하여 다음과 같이 변경합니다.
#import <UIKit/UIkit.h>
@class YourViewController;
@protocol YourViewController Delegate <NSObject>
@optional
-(void)defineDelegateMethodName: (YourViewController *) controller;
@required
-(BOOL)delegateMethodReturningBool: (YourViewController *) controller;
@end
@interface YourViewController : UIViewController
//Since the property for the protocol could be of any class, then it will be marked as a type of id.
@property (nonatomic, weak) id< YourViewController Delegate> delegate;
@end
프로토콜 동작에 정의된 메서드는 프로토콜 정의의 일부로 @optional 및 @required로 제어할 수 있습니다.
순서: 3: 위임자의 실시
#import "delegate.h"
@interface YourDelegateUser ()
<YourViewControllerDelegate>
@end
@implementation YourDelegateUser
- (void) variousFoo {
YourViewController *controller = [[YourViewController alloc] init];
controller.delegate = self;
}
-(void)defineDelegateMethodName: (YourViewController *) controller {
// handle the delegate being called here
}
-(BOOL)delegateMethodReturningBool: (YourViewController *) controller {
// handle the delegate being called here
return YES;
}
@end
//메서드를 호출하기 전에 메서드가 정의되어 있는지 여부를 테스트합니다.
- (void) someMethodToCallDelegate {
if ([[self delegate] respondsToSelector:@selector(defineDelegateMethodName:)]) {
[self.delegate delegateMethodName:self];
}
}
은 ★★★★★★★★★★★★★★★★★★★★★★★★★★★」Swift
「」의 delegate
.
그럼 대리인이란 무엇일까요?…소프트웨어 개발에는 일반적으로 발생하는 문제를 특정 컨텍스트 내에서 해결하는 데 도움이 되는 일반적인 재사용 가능한 솔루션 아키텍처가 있습니다. 이를테면 이러한 "구조"는 설계 패턴으로 가장 잘 알려져 있습니다.위임은 특정 이벤트가 발생할 때 한 개체가 다른 개체로 메시지를 보낼 수 있도록 하는 설계 패턴입니다.오브젝트 A가 오브젝트 B를 호출하여 액션을 실행한다고 가정합니다.조치가 완료되면 객체 A는 B가 작업을 완료했음을 알고 필요한 조치를 취해야 합니다. 이 작업은 딜러의 도움을 받아 수행할 수 있습니다.
더 자세한 설명은 Swift를 사용하여 클래스 간에 데이터를 전달하는 커스텀 대리인을 만드는 방법을 보여 드리겠습니다. 이 스타터 프로젝트를 다운로드 또는 복제하여 실행합니다.
두 클래스가 수 .ViewController A
★★★★★★★★★★★★★★★★★」ViewController B
는 두 을 누르면 .의 배경색이 .ViewController
무무복 ?? ??? 그럼 이제 B클래스에 대한 뷰를 탭 했을 때 A클래스의 배경색도 쉽게 바꿀 수 있도록 생각해 봅시다.
문제는 이 뷰가 클래스 B의 일부이며 클래스 A에 대해 전혀 모른다는 것입니다.따라서 이 두 클래스 간에 통신할 방법을 찾아야 합니다.이것이 위임이 빛을 발하는 부분입니다.실장을 6단계로 나누었으므로, 필요에 따라서 커닝 시트로 사용할 수 있습니다.
스텝 1: ClassBVC 파일에서 플러그마 마크1을 찾아 추가합니다.
//MARK: step 1 Add Protocol here.
protocol ClassBVCDelegate: class {
func changeBackgroundColor(_ color: UIColor?)
}
는 '만들다'를 입니다.protocol
B를 사용하다프로토콜 내에서는 구현 요건에 따라 원하는 수의 함수를 만들 수 있습니다.인 '이러다'를 할 수 있는 가 하나 있습니다.UIColor
, 의전, , , 의전, 의전, 의전, 의전, 의전, 의전, 의전, 의전, 의전, 의전, 의전, 의전, 의전, 의전, 의전, 의전, 의전, 의전, 의전, 의전, 의전, delegate
이 경우 클래스 이름의 끝에 있습니다.ClassBVCDelegate
.
2:를 찾습니다: 프래그마 마크2는 프래그마 마크2로 하겠습니다ClassVBC
을 덧붙입니다.
//MARK: step 2 Create a delegate property here.
weak var delegate: ClassBVCDelegate?
위임 됩니다.이은 반드시 이 속성을 .protocol
타이핑하다옵션이어야 합니다.또한 속성 앞에 weak 키워드를 추가하여 유지 사이클과 메모리 누수 가능성을 방지해야 합니다.현재로서는 그것이 무엇을 의미하는지 모르는 경우에는 이 키워드를 추가하는 것을 잊지 마십시오.
: handleTap 3단계에서 .method
ClassBVC
을 덧붙입니다.
//MARK: step 3 Add the delegate method call here.
delegate?.changeBackgroundColor(tapGesture.view?.backgroundColor)
앱을 실행하고 화면을 탭하면 새로운 동작을 볼 수 없습니다.그것은 맞지만, 제가 지적하고 싶은 것은 앱이 대리인을 호출해도 크래시 되지 않는다는 것입니다.또한 옵션값으로 작성하기 때문에 위임된 것이 존재하지 않는 경우에도 크래시 되지 않습니다. 이제 ,, 볼로 요?ClassAVC
파일링하여 위임받은 것을 만듭니다.
4: 내에서 .handleTap은 4의 마크입니다.ClassAVC
'나'는 '나'가 아니라 '나'가 아니라 '나'는 '나'가 아니라 '나'는 '나'입니다.
//MARK: step 4 conform the protocol here.
class ClassAVC: UIViewController, ClassBVCDelegate {
}
현재 AVC는 AVC를 했습니다.ClassBVCDelegate
protocol을"Type '(클래스)(클래스(클래스)를 입력하세요)"라는하고 있는 을 알 수 .AVC™ '클래스B'VDelegate' 프로토콜을 준수하지 않으며, 이는 단지 아직 프로토콜의 메서드를 사용하지 않았다는 것을 의미합니다. 클래스 A가 프로토콜을 채택할 때 클래스 B와 계약을 체결하는 것과 같으며 이 계약에는 "나를 채택하는 모든 클래스는 내 기능을 사용해야 합니다!"이치노
간단한 메모:만약 당신이 여기서 온다면Objective-C
그, 그 수 저나 만한 것은, 이 방법, 이 방법, 이 방법, 이 방법, 이 방법, 이 방법, 이 방법 등이 있습니다.Swift
에서는 옵션인 '무조건'을 .protocols
수 protocol
를 합니다.protocol
★★★★★★ 。
다른 합니다.protocols
이렇게 하면 오브젝트에 대해 하나의 책임을 부여한다는 개념을 따르지만, 구현 내용에 따라 달라질 수 있습니다.
여기 옵션 메서드에 대한 좋은 기사가 있습니다.
5단계: prepare for segue 메서드에서 5단계 플러그마크를 찾아 추가합니다.
//MARK: step 5 create a reference of Class B and bind them through the `prepareforsegue` method.
if let nav = segue.destination as? UINavigationController, let classBVC = nav.topViewController as? ClassBVC {
classBVC.delegate = self
}
에서는 그냥 '아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 예.ClassBVC
그 해 주는데, 자신이다, 자기 자신이다, 자기 자신이다. 쎄,, 란란란ClassAVC
★★★★★★★★★★★★★★★★★!
6:으로 6에서 .ClassAVC
그럼 이제 이 해 볼까요?protocol
func changeBackgroundColor 라고 입력하면 자동으로 완료됨을 알 수 있습니다.그 안에 실장을 추가할 수 있습니다.이 예에서는 배경색을 변경하여 추가합니다.
//MARK: step 6 finally use the method of the contract
func changeBackgroundColor(_ color: UIColor?) {
view.backgroundColor = color
}
이제 앱을 실행하세요!
Delegates
에 널려 있어서 못하고 될.tableview
에서는 많은 의 '위임 '위임', ''UIKIT
및 많은 frameworks
또한, 그들은 이러한 주요 문제들을 해결한다.
- 물체가 단단히 결합되지 않도록 하십시오.
- 오브젝트를 서브클래스 할 필요 없이 동작과 외관을 변경할 수 있습니다.
- 임의 개체로 작업을 처리할 수 있습니다.
대리인을 이것만 거입니다. 방금 커스텀 딜리버를 구현했습니다.이것만으로 많은 문제를 생각하고 있는 것을 알고 있습니다.위임을 이해하는 것은 매우 중요한 디자인 패턴입니다.iOS
오브젝트 간에 1대 1의 관계가 있다는 것을 항상 염두에 두십시오.
오리지널 튜토리얼은 이쪽에서 보실 수 있습니다.
답변은 실제로 이루어지지만, 대리인을 만들기 위한 "치트 시트"를 드리고 싶습니다.
DELEGATE SCRIPT
CLASS A - Where delegate is calling function
@protocol <#Protocol Name#> <NSObject>
-(void)delegateMethod;
@end
@interface <#Some ViewController#> : <#UIViewController#>
@property (nonatomic, assign) id <<#Protocol Name#>> delegate;
@end
@implementation <#Some ViewController#>
-(void)someMethod {
[self.delegate methodName];
}
@end
CLASS B - Where delegate is called
@interface <#Other ViewController#> (<#Delegate Name#>) {}
@end
@implementation <#Other ViewController#>
-(void)otherMethod {
CLASSA *classA = [[CLASSA alloc] init];
[classA setDelegate:self];
}
-delegateMethod() {
}
@end
View Controller.h
@protocol NameDelegate <NSObject>
-(void)delegateMEthod: (ArgType) arg;
@end
@property id <NameDelegate> delegate;
View Controller.m
[self.delegate delegateMEthod: argument];
MainViewController.m
ViewController viewController = [ViewController new];
viewController.delegate = self;
방법:
-(void)delegateMEthod: (ArgType) arg{
}
내 관점에서는 위임 메서드에 대해 별도의 클래스를 만들면 원하는 장소에서 사용할 수 있습니다.
[ Custom Drop Down Class . h ]으로 이동합니다.
typedef enum
{
DDSTATE,
DDCITY
}DropDownType;
@protocol DropDownListDelegate <NSObject>
@required
- (void)dropDownDidSelectItemWithString:(NSString*)itemString DropDownType:(DropDownType)dropDownType;
@end
@interface DropDownViewController : UIViewController
{
BOOL isFiltered;
}
@property (nonatomic, assign) DropDownType dropDownType;
@property (weak) id <DropDownListDelegate> delegate;
@property (strong, nonatomic) NSMutableArray *array1DropDown;
@property (strong, nonatomic) NSMutableArray *array2DropDown;
그 후 in.m 파일 오브젝트를 사용하여 어레이를 만듭니다.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
CGFloat rowHeight = 44.0f;
return rowHeight;
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return isFiltered?[self.array1DropDown count]:[self.array2DropDown count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *simpleTableIdentifier = @"TableCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
if (self.delegate) {
if (self.dropDownType == DDCITY) {
cell.textLabel.text = [self.array1DropDown objectAtIndex:indexPath.row];
}
else if (self.dropDownType == DDSTATE) {
cell.textLabel.text = [self.array2DropDown objectAtIndex:indexPath.row];
}
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self dismissViewControllerAnimated:YES completion:^{
if(self.delegate){
if(self.dropDownType == DDCITY){
[self.delegate dropDownDidSelectItemWithString:[self.array1DropDown objectAtIndex:indexPath.row] DropDownType:self.dropDownType];
}
else if (self.dropDownType == DDSTATE) {
[self.delegate dropDownDidSelectItemWithString:[self.array2DropDown objectAtIndex:indexPath.row] DropDownType:self.dropDownType];
}
}
}];
}
여기서는 모두 커스텀 위임 클래스로 설정됩니다.그런 다음 원하는 곳에서 위임 방법을 사용할 수 있습니다.예를 들어...
그 후 다른 뷰컨트롤러 Import에서
이와 같은 위임 메서드를 호출하기 위한 작업을 만듭니다.
- (IBAction)dropDownBtn1Action:(id)sender {
DropDownViewController *vehicleModelDropView = [[DropDownViewController alloc]init];
vehicleModelDropView.dropDownType = DDCITY;
vehicleModelDropView.delegate = self;
[self presentViewController:vehicleModelDropView animated:YES completion:nil];
}
이 콜 대리자 방식 이후
- (void)dropDownDidSelectItemWithString:(NSString *)itemString DropDownType:(DropDownType)dropDownType {
switch (dropDownType) {
case DDCITY:{
if(itemString.length > 0){
//Here i am printing the selected row
[self.dropDownBtn1 setTitle:itemString forState:UIControlStateNormal];
}
}
break;
case DDSTATE: {
//Here i am printing the selected row
[self.dropDownBtn2 setTitle:itemString forState:UIControlStateNormal];
}
default:
break;
}
}
위임:- 작성
@protocol addToCartDelegate <NSObject>
-(void)addToCartAction:(ItemsModel *)itemsModel isAdded:(BOOL)added;
@end
전송하고 데이터를 보내는 보기에 위임자를 할당하십시오.
[self.delegate addToCartAction:itemsModel isAdded:YES];
//1.
//Custom delegate
@protocol TB_RemovedUserCellTag <NSObject>
-(void)didRemoveCellWithTag:(NSInteger)tag;
@end
//2.
//Create a weak reference in a class where you declared the delegate
@property(weak,nonatomic)id <TB_RemovedUserCellTag> removedCellTagDelegate;
//3.
// use it in the class
[self.removedCellTagDelegate didRemoveCellWithTag:self.tag];
//4. import the header file in the class where you want to conform to the protocol
@interface MyClassUsesDelegate ()<TB_RemovedUserCellTag>
@end
//5. 클래스 .m - (void)didRemoveCellWithTag: (NSInterger)태그 {NSLog@("Tag %d", tag)에서 메서드를 구현합니다.
}
예를 들어 온라인으로 제품을 구입하면 배송/배송 등 다른 팀에서 처리하는 과정을 거칩니다.따라서 배송이 완료되면 배송팀은 배송팀에 통지해야 합니다.이 정보를 방송하는 것은 다른 사람에게 오버헤드가 되기 때문에/벤더는 이 정보를 필요한 사람에게만 전달하고 싶을 수 있습니다.
즉, 앱의 관점에서 보면 이벤트는 온라인 주문이 될 수 있고, 다른 팀은 여러 뷰가 될 수 있습니다.
다음은 Shipping View를 Shipping team으로, Delivery View를 Delivery team으로 코드화한 예입니다.
//Declare the protocol with functions having info which needs to be communicated
protocol ShippingDelegate : class {
func productShipped(productID : String)
}
//shippingView which shows shipping status of products
class ShippingView : UIView
{
weak var delegate:ShippingDelegate?
var productID : String
@IBAction func checkShippingStatus(sender: UIButton)
{
// if product is shipped
delegate?.productShipped(productID: productID)
}
}
//Delivery view which shows delivery status & tracking info
class DeliveryView: UIView,ShippingDelegate
{
func productShipped(productID : String)
{
// update status on view & perform delivery
}
}
//Main page on app which has both views & shows updated info on product whole status
class ProductViewController : UIViewController
{
var shippingView : ShippingView
var deliveryView : DeliveryView
override func viewDidLoad() {
super.viewDidLoad()
// as we want to update shipping info on delivery view, so assign delegate to delivery object
// whenever shipping status gets updated it will call productShipped method in DeliveryView & update UI.
shippingView.delegate = deliveryView
//
}
}
한 장의 그림은 천 마디 이상의 단어이다:-P
''greeter
main
Objective-C 코드는 대리자로 알려져 있으며 이는 순수 가상 함수의 클래스를 구현하는 객체에 대한 C++ 포인터에 지나지 않습니다.
언급URL : https://stackoverflow.com/questions/626898/how-do-i-create-delegates-in-objective-c
'source' 카테고리의 다른 글
글로벌 변수 작성 방법 (0) | 2023.04.19 |
---|---|
WPF와 Silverlight의 비교 (0) | 2023.04.19 |
월별 및 연도별 SQL 그룹화 (0) | 2023.04.19 |
Excel 어레이에 논리 OR을 적용하는 방법 (0) | 2023.04.14 |
Windows XP 이후의 Windows:창을 표시하지 않고 백그라운드에서 배치 파일을 실행하려면 어떻게 해야 합니까? (0) | 2023.04.14 |