iOS runtime 실전 응용:연결 대상
전언
시작하기 전에 iOSruntime의 기초 이해편: iOS 내공편:runtime
유통자는 면접을 볼 때'NSArray에 어떻게 속성을 추가하는가(상속을 사용할 수 없다)'라는 질문에 즉시 협박을 당했다. 상속을 사용할 수 없는데 분류를 쓰겠는가?그러나 분류는 방법만 추가할 수 있을 것 같고 속성을 추가할 수 없을 것 같아서 통자는 백 번 생각해도 이해할 수 없었다. 나중에 런타임을 접하고 나서야 문득 깨달았다.
연결 개체란?
관련 대상은 어떤 OC 대상이 하나의 유일한 키를 통해 하나의 클래스에 연결된 실례를 가리킨다.예를 들어 xiaoming은 Persong류의 실례이다. 그의 Dog(OC 대상)은 밧줄(key)을 통해 그에게 끌려 산책을 한다. 이것은 xiaoming과 Dog가 관련이 있다고 할 수 있다. 물론 xiaoming은 여러 개의 Dog를 끌 수 있다.
어떻게 대상을 연결합니까
runtime가 제공하는 방법:
//
void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)
//
id objc_getAssociatedObject(id object, const void *key)
//
void objc_removeAssociatedObjects(id object)
변수 설명:
id object: ( xiaoming)
const void *key: key,
id value: ( dog)
objc_AssociationPolicy policy:
objc_AssociationPolicy policy의 enum 값은 다음과 같습니다.
OBJC_ASSOCIATION_ASSIGN = 0,
OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1,
OBJC_ASSOCIATION_COPY_NONATOMIC = 3,
OBJC_ASSOCIATION_RETAIN = 01401,
OBJC_ASSOCIATION_COPY = 01403
객체가 해제되면 연관된 객체의 해제 여부가 이 정책에 따라 결정되며, 정책이 RETAIN/COPY인 경우 연관된 객체는 해제(release)되며, ASSIGN인 경우에는 해제되지 않습니다.주의해야 할 것은, 우리는removeAssociated를 주동적으로 호출해서 관련 대상을 접촉할 필요가 없고, 지정한 대상을 해제할 필요가 있으면 setassociatedObject를nil로 설정하여 실현할 수 있다.
연관된 객체의 응용
1. 공통 속성 추가
이것은 가장 자주 사용하는 모델이다. 일반적으로 우리는 클래스 성명에 속성을 추가하지만 특정한 수요(예를 들어 앞에서 설명한 경우)에서 분류에 하나 이상의 속성을 추가해야 하면 컴파일러가 오류를 보고한다. 이 문제의 해결 방안은runtime의 관련 대상을 사용하는 것이다.응용 예: 우리는tabbar를 사용자 정의하고 공공의 속성과 방법을 노출해야 한다.(독자들은 계승과 분류로 이루어진 장점과 부족한 점을 생각할 수 있다)
@interface UITabBarController (Custom)
@property (nonatomic, strong) SUCustomTabbar * customTabbar;
@end
#import "UITabBarController+Custom.h"
#import
@implementation UITabBarController (Custom)
- (void)setCustomTabbar:(UIView *)customTabbar {
// key
objc_setAssociatedObject(self, @selector(customTabbar), customTabbar, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (UIView *)customTabbar {
return objc_getAssociatedObject(self, @selector(customTabbar));
}
// ...
@end
이렇게 하면 우리는 원래의 tabbar처럼 사용자 정의 tabbar를 사용할 수 있다.
[self.tabBarController.customTabbar doSomgthig];
2. 개인 구성원 변수 추가
때때로 분류에 공공 성명에 노출되고 싶지 않은 구성원 변수를 추가해야 한다.응용 예: 버튼에 클릭 시간의 리셋을 추가합니다
@interface UIButton (Callback)
- (instancetype)initWithFrame:(CGRect)frame callback:(void (^)(UIButton *))callbackBlock;
@end
@interface UIButton ()
@property (nonatomic, copy) void (^callbackBlock)(UIButton * button);
@end
@implementation UIButton (Callback)
- (void (^)(UIButton *))callbackBlock {
return objc_getAssociatedObject(self, @selector(callbackBlock));
}
- (void)setCallbackBlock:(void (^)(UIButton *))callbackBlock {
objc_setAssociatedObject(self, @selector(callbackBlock), callbackBlock, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (instancetype)initWithFrame:(CGRect)frame callback:(void (^)(UIButton *))callbackBlock {
if (self = [super initWithFrame:frame]) {
self.callbackBlock = callbackBlock;
[self addTarget:self action:@selector(didClickAction:) forControlEvents:UIControlEventTouchUpInside];
}
return self;
}
- (void)didClickAction:(UIButton *)button {
self.callbackBlock(button);
}
@end
독자 사고: 상기 코드에 메모리 관리 문제가 존재할 수 있는지
3. 관련 KVO 관찰자는 때때로 우리가 분류에서 KVO를 사용하는데 관련 대상을 관찰자로 사용하고 대상이 자신을 관찰하는 것을 최대한 피한다.이 응용 모델은 더 이상 예를 들지 않고 관심 있는 독자들은 스스로 깊이 연구하거나 코드를 평론에 붙일 수 있다.
사색
1. 관련 대상이 더 많은 응용 모델?2. 관련 대상이 문제 해결의 첫 번째 선택입니까?3. 관련 대상의 부작용?
여러분의 교류와 토론을 환영합니다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.