(10) [OC 고효율 시리즈] 기존 클래스에서 관련 대상을 사용하여 사용자 정의 데이터를 저장한다
동적 생성 포인터가 한 대상에서 다른 대상을 가리키고 해당하는'메모리 관리 의미'를 따르는 것을 말한다. 이것은 동적으로 하나의 속성을 추가하는 것과 같다.
2. 관련 유형과 같은 효과의property 속성
연관 유형
같은 @property 속성
OBJC_ASSOCIATION_ASSIGN
assign
OBJC_ASSOCIATION_RETAIN_NONATOMIC
nonatomic, retain
OBJC_ASSOCIATION_COPY_NONATOMIC
nonatomic, copy
OBJC_ASSOCIATION_RETAIN
retain
3. 관련api
연결 객체 설정
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)
4. 정적 글로벌 변수를 키로
5. 관련 대상을 사용하면 좋은 점이 어디에 있습니까?속성을 확장하려면 하위 클래스를 만들면 되지 않습니까?
계승적인 방식으로 속성을 확장하면 코드가 침입성을 가진다.OC에서는 단일 상속 모드로 A를 상속하면 B를 상속할 수 없고 또 다른 C도 있다.그래서 어떤 특정한 상황에서는 상속을 사용할 수 없다.
더 많은 것은 분류 + 관련 방식을 사용하여 이미 존재하는 클래스를 확장하는 것이다.이런 코드는 침입성이 없어서 사용하기에 더욱 간단하고 간편하다.
6.UIImageView+WebCache에 사용된 연관
UIImageView + WebCache에서 새 그림을 설정할 때마다 현재 이미지 뷰가 불러오는 프로세스를 취소합니다.이러한 프로세스 대상은 연결된 방식으로 이미지뷰에 동적으로 연결되는 것이다.
//UIImageView+WebCache.m
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock {
[self sd_cancelCurrentImageLoad];
...
if (url) {
__weak UIImageView *wself = self;
id operation = [SDWebImageManager.sharedManager downloadImageWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
...
}];
[self sd_setImageLoadOperation:operation forKey:@"UIImageViewImageLoad"];
} else {
...
}
}
- (void)sd_cancelCurrentImageLoad {
[self sd_cancelImageLoadOperationWithKey:@"UIImageViewImageLoad"];
}
//UIView+WebCacheOperation.m
- (NSMutableDictionary *)operationDictionary {
NSMutableDictionary *operations = objc_getAssociatedObject(self, &loadOperationKey);
if (operations) {
return operations;
}
operations = [NSMutableDictionary dictionary];
objc_setAssociatedObject(self, &loadOperationKey, operations, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
return operations;
}
- (void)sd_setImageLoadOperation:(id)operation forKey:(NSString *)key {
[self sd_cancelImageLoadOperationWithKey:key];
NSMutableDictionary *operationDictionary = [self operationDictionary];
[operationDictionary setObject:operation forKey:key];
}
7. 관련을 사용하면 delegate 형식으로 인해 분산된 코드를 Block 형식으로 집중시킬 수 있다.이렇게 하면 가독성이 더욱 강하고 코드가 더욱 간결하다.
UIactionSheet의 경우
먼저 관련을 사용하지 않을 때의 코드를 하나 주세요.
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
- (IBAction)didClickBtn:(UIButton *)btn{
UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:@"Hellow World" delegate:self cancelButtonTitle:@" hellow" destructiveButtonTitle:@"hellow1" otherButtonTitles:@"hellow2",nil];
[sheet showInView:self.view];
}
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{
NSLog(@" %ld",buttonIndex);
}
@end
이렇게 actionsheet을 눌렀을 때의 논리와 창설된 코드는 분리되어 있으며 코드가 많을 때 이 프록시 방법은 다른 프록시 방법과 함께 놓으면 가독성이 비교적 떨어진다.또한 UIACtion Sheet을 만들 때마다 다음이 필요합니다.
연결을 사용하면 ActionSheet의 관련 논리를 하나의 Tool로 독립할 수 있습니다. 코드는 다음과 같습니다.
//.m
static char tool;
static char sheet;
@interface YXActionSheetTool ()
@property (nonatomic,copy) void(^callback)(NSInteger clickIndex);
@property (nonatomic,weak) UIViewController *controller;
@end
@implementation YXActionSheetTool
+ (void)showWithController:(UIViewController *)controller title:(NSString *)title cancleTitle:(NSString *)cancleTitle destructiveTitle:(NSString *)destructiveTitle otherTitles:(NSArray *)otherTitles callback:(void(^)(NSInteger clickIndex))callback {
UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:title delegate:nil cancelButtonTitle:cancleTitle destructiveButtonTitle:destructiveTitle otherButtonTitles:nil];
for (NSString *otherTitle in otherTitles) {
[sheet addButtonWithTitle:otherTitle];
}
YXActionSheetTool *actionSheetTool = [[YXActionSheetTool alloc] init];
objc_setAssociatedObject(controller,&tool,actionSheetTool,OBJC_ASSOCIATION_RETAIN_NONATOMIC);// tool
objc_setAssociatedObject(actionSheetTool,&sheet,sheet,OBJC_ASSOCIATION_RETAIN_NONATOMIC);
actionSheetTool.callback=callback;
actionSheetTool.controller =controller;
sheet.delegate=actionSheetTool;
[sheet showInView:controller.view];
}
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{
objc_setAssociatedObject(self,&sheet,nil,OBJC_ASSOCIATION_RETAIN_NONATOMIC);
objc_setAssociatedObject(self.controller,&tool,nil,OBJC_ASSOCIATION_RETAIN_NONATOMIC);
if(self.callback)
self.callback(buttonIndex);
}
@end
호출 코드는 다음과 같습니다
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
- (IBAction)didClickBtn:(UIButton *)btn{
[YXActionSheetTool showWithController:self title:@"Hellow World" cancleTitle:@" hellow" destructiveTitle:@"hellow1" otherTitles:@[@"hellow2"] callback:^(NSInteger clickIndex) {
NSLog(@" %ld",clickIndex);
}];
}
@end
이렇게 하면 ui 코드와 논리 코드가 함께 있어 읽기에 편리하다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.