From 1d8cea43fa8f1475a7bb2dac190c5f633eef4e16 Mon Sep 17 00:00:00 2001 From: jg zhu <13913514919@189.cn> Date: Thu, 16 Sep 2021 19:15:48 +0800 Subject: [PATCH] Release 3.1.7 --- SensorsAnalyticsSDK.podspec | 2 +- SensorsAnalyticsSDK.xcodeproj/project.pbxproj | 9 +- SensorsAnalyticsSDK/Core/SAModuleManager.m | 13 ++- .../Core/SensorsAnalyticsSDK.m | 2 +- .../Core/Utils/SAThreadSafeDictionary.h | 40 +++++++++ .../Core/Utils/SAThreadSafeDictionary.m | 90 +++++++++++++++++++ 6 files changed, 145 insertions(+), 11 deletions(-) create mode 100644 SensorsAnalyticsSDK/Core/Utils/SAThreadSafeDictionary.h create mode 100644 SensorsAnalyticsSDK/Core/Utils/SAThreadSafeDictionary.m diff --git a/SensorsAnalyticsSDK.podspec b/SensorsAnalyticsSDK.podspec index ff3f94e2..2677a775 100644 --- a/SensorsAnalyticsSDK.podspec +++ b/SensorsAnalyticsSDK.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "SensorsAnalyticsSDK" - s.version = "3.1.6" + s.version = "3.1.7" s.summary = "The official iOS SDK of Sensors Analytics." s.homepage = "http://www.sensorsdata.cn" s.source = { :git => 'https://github.com/sensorsdata/sa-sdk-ios.git', :tag => "v#{s.version}" } diff --git a/SensorsAnalyticsSDK.xcodeproj/project.pbxproj b/SensorsAnalyticsSDK.xcodeproj/project.pbxproj index 99e7a08b..28e8010b 100644 --- a/SensorsAnalyticsSDK.xcodeproj/project.pbxproj +++ b/SensorsAnalyticsSDK.xcodeproj/project.pbxproj @@ -30,6 +30,8 @@ 45A565BD263C17E400C9C41B /* SAReferrerManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 45A565B9263C17E400C9C41B /* SAReferrerManager.m */; }; 45A565BE263C17E400C9C41B /* SAAppLifecycle.m in Sources */ = {isa = PBXBuildFile; fileRef = 45A565BA263C17E400C9C41B /* SAAppLifecycle.m */; }; 45A565BF263C17E400C9C41B /* SAAppLifecycle.h in Headers */ = {isa = PBXBuildFile; fileRef = 45A565BB263C17E400C9C41B /* SAAppLifecycle.h */; }; + 45BD80CE26F0B49700DCC759 /* SAThreadSafeDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = 45BD80CC26F0B49700DCC759 /* SAThreadSafeDictionary.h */; }; + 45BD80CF26F0B49700DCC759 /* SAThreadSafeDictionary.m in Sources */ = {isa = PBXBuildFile; fileRef = 45BD80CD26F0B49700DCC759 /* SAThreadSafeDictionary.m */; }; 4D14F13E25FC5BF200113EA2 /* SAVisualizedUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D14F13C25FC5BF200113EA2 /* SAVisualizedUtils.m */; }; 4D14F13F25FC5BF200113EA2 /* SAVisualizedUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D14F13D25FC5BF200113EA2 /* SAVisualizedUtils.h */; }; 4D14F16C25FC646A00113EA2 /* SAViewNodeTree.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D14F16A25FC646A00113EA2 /* SAViewNodeTree.h */; }; @@ -329,6 +331,8 @@ 45A565B9263C17E400C9C41B /* SAReferrerManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SAReferrerManager.m; sourceTree = ""; }; 45A565BA263C17E400C9C41B /* SAAppLifecycle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SAAppLifecycle.m; sourceTree = ""; }; 45A565BB263C17E400C9C41B /* SAAppLifecycle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SAAppLifecycle.h; sourceTree = ""; }; + 45BD80CC26F0B49700DCC759 /* SAThreadSafeDictionary.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SAThreadSafeDictionary.h; sourceTree = ""; }; + 45BD80CD26F0B49700DCC759 /* SAThreadSafeDictionary.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SAThreadSafeDictionary.m; sourceTree = ""; }; 4D14F13C25FC5BF200113EA2 /* SAVisualizedUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SAVisualizedUtils.m; sourceTree = ""; }; 4D14F13D25FC5BF200113EA2 /* SAVisualizedUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SAVisualizedUtils.h; sourceTree = ""; }; 4D14F16A25FC646A00113EA2 /* SAViewNodeTree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SAViewNodeTree.h; sourceTree = ""; }; @@ -961,6 +965,8 @@ 4D2D53B12591EB3900805141 /* SAValidator.m */, 4D2D53A92591EB3900805141 /* SAWeakPropertyContainer.h */, 4D2D53AB2591EB3900805141 /* SAWeakPropertyContainer.m */, + 45BD80CC26F0B49700DCC759 /* SAThreadSafeDictionary.h */, + 45BD80CD26F0B49700DCC759 /* SAThreadSafeDictionary.m */, ); path = Utils; sourceTree = ""; @@ -1419,8 +1425,8 @@ 4DD1296A25F8E451008C0B1E /* SAViewNode.h in Headers */, A8356DC52656459A00FD64AA /* SAAppTracker.h in Headers */, 883BAAB02669CD18008105D2 /* SAExceptionManager.h in Headers */, + 45BD80CE26F0B49700DCC759 /* SAThreadSafeDictionary.h in Headers */, F22E1B1B26A55C8A0033A748 /* SAAppPageLeaveTracker.h in Headers */, - 881A41FF253D7B5000854F69 /* SATrackTimer.h in Headers */, 4DD1285925F872A4008C0B1E /* SAEnumDescription.h in Headers */, 4DD1285D25F872A4008C0B1E /* SAVisualizedConnection.h in Headers */, A8356DCF2656459A00FD64AA /* SAGestureViewProcessorFactory.h in Headers */, @@ -1715,6 +1721,7 @@ 4DA89BC425C2BC1E003ABA43 /* SAReachability.m in Sources */, F277F5CB25CF9A43009B5CE6 /* SAAppPushConstants.m in Sources */, 4DD1286325F872A4008C0B1E /* SAVisualizedAutoTrackObjectSerializer.m in Sources */, + 45BD80CF26F0B49700DCC759 /* SAThreadSafeDictionary.m in Sources */, 881A4193253D7B4F00854F69 /* SensorsAnalyticsSDK.m in Sources */, 4D2D53C62591EB3A00805141 /* SACommonUtility.m in Sources */, 4D2D53A22591EB2100805141 /* SAEventRecord.m in Sources */, diff --git a/SensorsAnalyticsSDK/Core/SAModuleManager.m b/SensorsAnalyticsSDK/Core/SAModuleManager.m index 61b92ab2..57aad356 100644 --- a/SensorsAnalyticsSDK/Core/SAModuleManager.m +++ b/SensorsAnalyticsSDK/Core/SAModuleManager.m @@ -26,6 +26,7 @@ #import "SAModuleProtocol.h" #import "SAConfigOptions.h" #import "SensorsAnalyticsSDK+Private.h" +#import "SAThreadSafeDictionary.h" // Location 模块名 static NSString * const kSALocationModuleName = @"Location"; @@ -48,7 +49,7 @@ @interface SAModuleManager () /// 已开启的模块 -@property (atomic, strong) NSMutableDictionary> *modules; +@property (nonatomic, strong) SAThreadSafeDictionary> *modules; @property (nonatomic, strong) SAConfigOptions *configOptions; @@ -120,7 +121,7 @@ + (instancetype)sharedInstance { static SAModuleManager *manager = nil; dispatch_once(&onceToken, ^{ manager = [[SAModuleManager alloc] init]; - manager.modules = [NSMutableDictionary dictionary]; + manager.modules = [SAThreadSafeDictionary dictionary]; }); return manager; } @@ -260,10 +261,8 @@ @implementation SAModuleManager (Property) - (NSDictionary *)properties { NSMutableDictionary *properties = [NSMutableDictionary dictionary]; - // 这里需要做一次 copy 操作,避免多线程中同时操作 modules 导致崩溃 - NSDictionary *dictionary = [self.modules copy]; // 兼容使用宏定义的方式源码集成 SDK - [dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *key, id obj, BOOL *stop) { + [self.modules enumerateKeysAndObjectsUsingBlock:^(NSString *key, id obj, BOOL *stop) { if (!([obj conformsToProtocol:@protocol(SAPropertyModuleProtocol)] && [obj respondsToSelector:@selector(properties)]) || !obj.isEnable) { return; } @@ -418,9 +417,7 @@ @implementation SAModuleManager (JavaScriptBridge) - (NSString *)javaScriptSource { NSMutableString *source = [NSMutableString string]; - // 这里需要做一次 copy 操作,避免多线程中同时操作 modules 导致崩溃 - NSDictionary *dictionary = [self.modules copy]; - [dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *key, id obj, BOOL *stop) { + [self.modules enumerateKeysAndObjectsUsingBlock:^(NSString *key, id obj, BOOL *stop) { if (!([obj conformsToProtocol:@protocol(SAJavaScriptBridgeModuleProtocol)] && [obj respondsToSelector:@selector(javaScriptSource)]) || !obj.isEnable) { return; } diff --git a/SensorsAnalyticsSDK/Core/SensorsAnalyticsSDK.m b/SensorsAnalyticsSDK/Core/SensorsAnalyticsSDK.m index 54a88938..62fdf8d8 100755 --- a/SensorsAnalyticsSDK/Core/SensorsAnalyticsSDK.m +++ b/SensorsAnalyticsSDK/Core/SensorsAnalyticsSDK.m @@ -41,7 +41,7 @@ #import "SAProfileEventObject.h" #import "SAJSONUtil.h" -#define VERSION @"3.1.6" +#define VERSION @"3.1.7" void *SensorsAnalyticsQueueTag = &SensorsAnalyticsQueueTag; diff --git a/SensorsAnalyticsSDK/Core/Utils/SAThreadSafeDictionary.h b/SensorsAnalyticsSDK/Core/Utils/SAThreadSafeDictionary.h new file mode 100644 index 00000000..fe0f0a86 --- /dev/null +++ b/SensorsAnalyticsSDK/Core/Utils/SAThreadSafeDictionary.h @@ -0,0 +1,40 @@ +// +// SAThreadSafeDictionary.h +// SensorsAnalyticsSDK +// +// Created by yuqiang on 2021/9/14. +// Copyright © 2021 Sensors Data Co., Ltd. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface SAThreadSafeDictionary : NSObject + ++ (SAThreadSafeDictionary *)dictionary; + +@property (readonly, copy) NSArray *allKeys; +@property (readonly, copy) NSArray *allValues; + +- (nullable ObjectType)objectForKeyedSubscript:(KeyType)key; +- (void)setObject:(nullable ObjectType)obj forKeyedSubscript:(KeyType )key; + +- (void)removeObjectForKey:(KeyType)aKey; +- (void)enumerateKeysAndObjectsUsingBlock:(void (NS_NOESCAPE ^)(KeyType key, ObjectType obj, BOOL *stop))block; + +@end + +NS_ASSUME_NONNULL_END diff --git a/SensorsAnalyticsSDK/Core/Utils/SAThreadSafeDictionary.m b/SensorsAnalyticsSDK/Core/Utils/SAThreadSafeDictionary.m new file mode 100644 index 00000000..12d13c01 --- /dev/null +++ b/SensorsAnalyticsSDK/Core/Utils/SAThreadSafeDictionary.m @@ -0,0 +1,90 @@ +// +// SAThreadSafeDictionary.m +// SensorsAnalyticsSDK +// +// Created by yuqiang on 2021/9/14. +// Copyright © 2021 Sensors Data Co., Ltd. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#if ! __has_feature(objc_arc) +#error This file must be compiled with ARC. Either turn on ARC for the project or use -fobjc-arc flag on this file. +#endif + +#import "SAThreadSafeDictionary.h" + +@interface SAThreadSafeDictionary () + +@property (nonatomic, strong) NSMutableDictionary *dictionary; +@property (nonatomic, strong) NSLock *lock; + +@end + +@implementation SAThreadSafeDictionary + +#pragma mark - init + ++ (SAThreadSafeDictionary *)dictionary { + return [[SAThreadSafeDictionary alloc] init]; +} + +- (instancetype)init { + self = [super init]; + if (self) { + _dictionary = [NSMutableDictionary dictionary]; + _lock = [[NSLock alloc] init]; + } + return self; +} + +- (id)objectForKeyedSubscript:(id)key { + [self.lock lock]; + id result = [self.dictionary objectForKeyedSubscript:key]; + [self.lock unlock]; + return result; +} + +- (void)setObject:(id)obj forKeyedSubscript:(id)key { + [self.lock lock]; + [self.dictionary setObject:obj forKeyedSubscript:key]; + [self.lock unlock]; +} + +- (NSArray *)allKeys { + [self.lock lock]; + NSArray *result = [self.dictionary allKeys]; + [self.lock unlock]; + return result; +} + +- (NSArray *)allValues { + [self.lock lock]; + NSArray *result = [self.dictionary allValues]; + [self.lock unlock]; + return result; +} + +- (void)removeObjectForKey:(id)key { + [self.lock lock]; + [self.dictionary removeObjectForKey:key]; + [self.lock unlock]; +} + +- (void)enumerateKeysAndObjectsUsingBlock:(void (NS_NOESCAPE ^)(id _Nonnull, id _Nonnull, BOOL * _Nonnull))block { + [self.lock lock]; + [self.dictionary enumerateKeysAndObjectsUsingBlock:block]; + [self.lock unlock]; +} + +@end