-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Modifying lock to improve code performance #667
Modifying lock to improve code performance #667
Conversation
MJProperty *propertyObj = objc_getAssociatedObject(self, property); | ||
if (propertyObj == nil) { | ||
propertyObj = [[self alloc] init]; | ||
propertyObj.property = property; | ||
objc_setAssociatedObject(self, property, propertyObj, OBJC_ASSOCIATION_RETAIN_NONATOMIC); | ||
} | ||
MJExtensionSemaphoreSignal |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MJPropertySemaphoreCreate
MJ_LOCK(_propertySemaphore);
NSArray *cachedProperties = [self properties];
MJ_UNLOCK(_propertySemaphore);
在[self properties];
方法已加锁,此处并没有其他线程同时进入,所以并不需要加锁
MJPropertyType *type = types[code]; | ||
if (type == nil) { | ||
type = [[self alloc] init]; | ||
type.code = code; | ||
types[code] = type; | ||
} | ||
MJExtensionSemaphoreSignal |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
同上
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
上面有一些代码冗余的问题
MJExtension/NSObject+MJClass.m
Outdated
MJExtensionSemaphoreCreate | ||
MJExtensionSemaphoreWait | ||
MJClassSemaphoreCreate | ||
MJ_LOCK(_classSemaphore); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MJClassSemaphoreCreate
这里的宏, 并没有指出真正的变量内容
MJ_LOCK(_classSemaphore);
这里使用的 _classSemaphore
太隐含了.
dispatch_semaphore_wait(signalSemaphore, DISPATCH_TIME_FOREVER); | ||
|
||
#define MJExtensionSemaphoreSignal \ | ||
dispatch_semaphore_signal(signalSemaphore); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
上面删掉的代码在其他类里的改动和放在这里应该是一样的. define 宏定义只是在编译阶段替换而已.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
使用 MJ_LOCK ()
主要原因是不使用全局的一把锁,在每个对应的功能点加锁,后期如果还有线程安全相关问题,使用自己定义的锁,提高锁的效率:
MJ_LOCK(self.propertyKeysLock);
self.propertyKeysDict[key] = propertyKeys;
MJ_UNLOCK(self.propertyKeysLock);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
主要目的是不使用全局的那一把锁
修复
MJProperty
类中可变容器getter方法没有加锁引发线程安全问题的bug 多线程环境下崩溃 #660 (comment) .当前MJExtension使用全局的一把锁,影响效率:
a-> 针对全局静态容器,为每一个容器新建一把静态全局锁(总共两把静态锁,之前是一把静态锁)。
b-> 对于
MJProperty
中可变容器的锁跟随MJProperty
类的生命周期一起,不需要使用全局的锁。下面方法本来在
[self properties]
就加锁了,属于单一线程执行,没有必要再加锁: