为什么masonry的block里引用self不需要weak?

本文解释了在Masonry库中为什么可以在Block内直接使用self而不需要弱引用。通过分析Block的工作原理和Masonry的实现细节,揭示了栈Block执行完毕后即被释放的特性,避免了循环引用的问题。
为什么masonry的block里引用self不需要weak?

这个block只是个栈block,而且构不成循环引用的条件。栈block有个特性就是它执行完毕之后就出栈,出栈了就会被释放掉。看mas_makexxx的方法实现会发现这个block很快就被调用了,完事儿就出栈销毁,构不成循环引用,所以可以直接放心的使用self

栈是由系统管理的

我建立了一个文件夹TPBSkeletonManager,可以装对应的文件,请先帮我构思我要完成哪些文件才能更好帮我实现我的目标,注意模组设计可以参考下面的SDNDeviceDownloadImageManager // // SDNDeviceDownloadImageManager.h // Omada // // Created by wanghao on 2025/2/12. // Copyright © 2025 TP-Link. All rights reserved. // #import <Foundation/Foundation.h> NS_ASSUME_NONNULL_BEGIN @interface SDNDeviceDownloadImageManager : NSObject + (instancetype)sharedInstance; - (TPAbstractHandle *)checkDeviceUpgrade; - (UIImage *)deviceImage:(NSString *)deviceModel andModelVersion:(NSString *)modelVersion; @end NS_ASSUME_NONNULL_END // // SDNDeviceDownloadImageManager.m // Omada // // Created by wanghao on 2025/2/12. // Copyright © 2025 TP-Link. All rights reserved. // #import "SDNDeviceDownloadImageManager.h" #import "TPDataStorage.h" #import "SDWebImageManager.h" #import "DMSDNDeviceImageInfo.h" NSString *const kDeviceDownloadFirstVersion = @"0"; static const NSInteger kSDNDeviceDownloadDefaultCacheMaxCacheAge = 365 * 24 * 60 * 60 * 50; // 50 years static const NSInteger kSDNDeviceDownloadDefaultCacheMinUpdateInterval = 3 * 24 * 60 * 60; // 3 days @interface SDNDeviceDownloadImageManager () @property (nonatomic, readwrite, strong) TPECFetchDeviceIconModule *deviceIconModule; @property (nonatomic, readwrite, strong) TPAbstractHandle *checkDeviceUpdateHandle; @property (nonatomic, readwrite, copy) NSArray<DMSDNDeviceImageInfo *> *updateDeviceImageList; @property (nonatomic, readwrite, strong) SDWebImageDownloader *imageDownloader; @property (nonatomic, readwrite, strong) SDImageCache *imageCache; @property (nonatomic, readwrite, assign) BOOL isDownloading; @end @implementation SDNDeviceDownloadImageManager + (instancetype)sharedInstance { static id instance = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ instance = [[self alloc] init]; }); return instance; } - (instancetype)init { self = [super init]; if (self) { self.imageCache = [[SDImageCache alloc]initWithNamespace:@"OmadaDeviceStore"]; self.imageCache.maxCacheAge = kSDNDeviceDownloadDefaultCacheMaxCacheAge; self.imageDownloader = [SDWebImageDownloader sharedDownloader]; self.deviceIconModule = [ALAccountContext sharedInstance].eapCloudClient.fetchDeviceIconModule; self.updateDeviceImageList = [NSArray new]; self.isDownloading = NO; } return self; } - (TPAbstractHandle *)checkDeviceUpgrade { if (self.checkDeviceUpdateHandle) { return self.checkDeviceUpdateHandle; } NSString *currentVersion = [[TSSUserDefaults standardUserDefaults] objectForKey:TPDeviceIconCurrentVersionKey]; if (IsEmptyString(currentVersion)) { currentVersion = kDeviceDownloadFirstVersion; } TPWeakSelf TPQueueHandleFactoryBlock blck1 = ^TPAbstractHandle* (TPQueueHandleBlockContext* context){ TPStrongSelfNoReturn return [_self.deviceIconModule checkNeedUpgradeWithCurrentVersion:currentVersion]; }; TPQueueHandleFactoryBlock blck2 = ^TPAbstractHandle* (TPQueueHandleBlockContext* context){ TPStrongSelfNoReturn if(context.lastResult.success) { BOOL needCheckUp = _self.deviceIconModule.needUpdate; if (needCheckUp) { return [_self.deviceIconModule getDeviceIconWithCurrentVersion:currentVersion]; } } context.stop = YES; context.stopResult = context.lastResult; return nil; }; TPGCDQueueHandle *queueHandle = [[TPGCDQueueHandle alloc] initWithQueue:dispatch_get_main_queue() factoryBlockArray:@[blck1, blck2] timeout:-1]; [queueHandle addCompletionOnMainThread:^(TPHandleResult * _Nonnull result) { TPStrongSelf _self.checkDeviceUpdateHandle = nil; if (result.success) { _self.updateDeviceImageList = _self.deviceIconModule.updateDeviceImageList; if (_self.updateDeviceImageList.count > 0 && _self.deviceIconModule.needUpdate) { [_self downLoadUpdatedDeviceImage]; } } }]; return queueHandle; } - (void)updateCacheInfo { NSTimeInterval lastTime = 0.0; NSNumber *lastShowTimestampObject = [[TSSUserDefaults standardUserDefaults] objectForKey:TPDeviceIconLastUpdateTimeKey]; if (lastShowTimestampObject) { lastTime = [lastShowTimestampObject doubleValue]; } //上次更新时间距离现在超过最小间隔,则重新拉取设备图标 if (lastTime + kSDNDeviceDownloadDefaultCacheMinUpdateInterval < [[NSDate date] timeIntervalSince1970] && !self.isDownloading) { self.isDownloading = YES; [self resetCacheInfo]; [self checkDeviceUpgrade]; } } - (void)resetCacheInfo { [[TSSUserDefaults standardUserDefaults] setObject:kDeviceDownloadFirstVersion forKey:TPDeviceIconCurrentVersionKey]; [[TSSUserDefaults standardUserDefaults] setObject:[NSArray new] forKey:TPDeviceIconMdelListKey]; } - (void)storeDeviceModelList:(NSString *)modelAndVersionKey { if (IsEmptyString(modelAndVersionKey)) { return; } NSArray<NSString *> *imageList = [self deviceIconModelList]; for (NSString *itemImage in imageList) { if ([modelAndVersionKey isEqualToString:itemImage]) { return; } } imageList = [imageList arrayByAddingObject:modelAndVersionKey]; [[TSSUserDefaults standardUserDefaults] setObject:imageList forKey:TPDeviceIconMdelListKey]; } - (void)downLoadUpdatedDeviceImage { self.isDownloading = YES; __block int handledCount = 0; for (DMSDNDeviceImageInfo *deviceImageInfo in self.updateDeviceImageList) { if ([self.imageCache diskImageExistsWithKey:deviceImageInfo.modelAndVersionKey] || deviceImageInfo.imageDownLoadURL == nil) { [self storeDeviceModelList:deviceImageInfo.modelAndVersionKey]; handledCount++; [self updateControllerVersionWithTotalCount:handledCount]; continue; } TPWeakSelf [self.imageDownloader downloadImageWithURL:deviceImageInfo.imageDownLoadURL options:0 progress:nil completed:^(UIImage *image, NSData *data, NSError *error, BOOL finished) { TPStrongSelf handledCount++; [_self.imageCache storeImage:image recalculateFromImage:NO imageData:data forKey:deviceImageInfo.modelAndVersionKey toDisk:YES]; [self storeDeviceModelList:deviceImageInfo.modelAndVersionKey]; [[TSSUserDefaults standardUserDefaults] setObject:@([[NSDate date] timeIntervalSince1970]) forKey:TPDeviceIconLastUpdateTimeKey]; [_self updateControllerVersionWithTotalCount:handledCount]; }]; } } - (void)updateControllerVersionWithTotalCount:(int)totalCount { if (totalCount == self.updateDeviceImageList.count) { NSString *curVersion = [ALAccountContext sharedInstance].eapCloudClient.fetchDeviceIconModule.controllerVersion; [[TSSUserDefaults standardUserDefaults] setObject:curVersion forKey:TPDeviceIconCurrentVersionKey]; } } - (BOOL)hasDownLoadDevice:(NSString *)modelAndVersionKey { if (IsEmptyString(modelAndVersionKey)) { return NO; } return [self.imageCache diskImageExistsWithKey:modelAndVersionKey];; } - (UIImage *)deviceImage:(NSString *)deviceModel andModelVersion:(NSString *)modelVersion { NSString *modelAndVersionKey = [DMSDNDeviceImageInfo modelAndVersionKeyFromModel:deviceModel andVersion:modelVersion]; if (IsEmptyString(modelAndVersionKey)) { return nil; } UIImage *image = [self deviceImageFromModelAndVersionKey:modelAndVersionKey]; UIImage *finalImage = image == nil ? [self vigiDeviceImage:modelAndVersionKey] : image; if (finalImage == nil) { [self updateCacheInfo]; } return finalImage; } - (UIImage *)deviceImageFromModelAndVersionKey:(NSString *)modelAndVersionKey { UIImage *image = [self.imageCache imageFromDiskCacheForKey:modelAndVersionKey]; return image; } - (NSArray<NSString *> *)deviceIconModelList { NSArray<NSString *> *deviceModelList = [[TSSUserDefaults standardUserDefaults] objectForKey:TPDeviceIconMdelListKey]; return deviceModelList == nil ? [NSArray new] : deviceModelList; } - (UIImage *)vigiDeviceImage:(NSString *)modelAndVersionKey { NSArray<NSString *> *modelList = [self deviceIconModelList]; modelList = [modelList sortedArrayUsingComparator:^NSComparisonResult(NSString * obj1, NSString * obj2) { return obj1.length < obj2.length; }]; for (NSString *modelStr in modelList) { if (!IsEmptyString(modelAndVersionKey) && [modelAndVersionKey containsString:modelStr]) { return [self deviceImageFromModelAndVersionKey:modelStr]; } } return nil; } @end
最新发布
11-01
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值