gpt4 book ai didi

iphone - Objective-C 中的线程安全单例对象?

转载 作者:行者123 更新时间:2023-12-03 20:15:37 26 4
gpt4 key购买 nike

如何在 Objective-C 中创建线程安全的单例对象。例如。如果我有一个共享数据 Controller ,它是一个单例对象,如果两个或多个线程同时访问它会发生什么?或者这些对象默认具有线程安全性..?

更新:

在这种情况下,数据 Controller 属性内的对象是否决定它是否是线程安全的..?就像我的数据 Controller 有 NSMutableArray 并且它被设置为非原子它不会是线程安全的。在这种情况下它的值(value)会发生什么变化?

更新:2

@synchronized(self) 实际上做了什么......?

最佳答案

如果数据 Controller 不是线程安全的,则可能会发生未定义的行为 - 不惜一切代价避免它 =)

默认情况下,NSObject 绝对不是线程安全的。使用原子属性并不能使类成为线程安全的(补充说,因为这是一个流行的误解)。

典型的解决方案涉及确保所有可变状态都受到适当锁定(例如互斥锁或@synchronized)的保护。

当我说可变状态时,我指的是一个可以在外部或内部发生变化的对象。如果您不确定,请锁定以确保从多个线程读取或写入类型。这必须在阅读和写作时发生——始终如此。如果您有大量读取,读写锁可能是更好、更专业的锁。

要更详细地回答,您必须发布一些代码。

更新

Is it under this scenario that the objects inside the datacontroller's property decide if it is thread safe or not.. ? Like my datacontroller has NSMutableArray and it is set nonatomic it will not be thread safe. What will happen to its value in that case?

将其视为传递性。您的 NSMutableArray、它所保存的对象以及对它们的所有外部引用都必须以线程安全的方式使用,并且您必须跟踪所有这些。通常,您首先要减少共享的可变状态。不要给客户端提供对数组的引用,而是给他们数组所保存的元素的副本。同时,用锁保护所有读取、写入和元素复制。

为了简单起见,我将使用 @synchronize 进行演示:

@interface MONCookie : NSObject <NSCopying>

- (NSString *)name;

@end

@interface MONDataController : NSObject
{
@private
NSMutableArray * cookies; // << MONCookie[]
}

- (void)addCookie:(MONCookie *)cookie;

- (MONCookie *)cookieWithName:(NSString *)name;

@end

@implementation MONDataController

- (id)init
{
// no lock required here
self = [super init];
if (nil != self) {
cookies = [NSMutableArray new];
}
return self;
}

- (void)dealloc
{
// no lock required here
[cookies release], cookies = nil;
[super dealloc];
}

- (void)addCookie:(MONCookie *)cookie
{
@synchronized(self) { // now accessing cookies - lock required
[cookies addObject:cookie];
}
}

- (MONCookie *)cookieWithName:(NSString *)name
{
MONCookie * ret = nil;
@synchronized(self) { // now accessing cookies - lock required
for (MONCookie * at in cookies) {
if ([at.name isEqualToString:name]) {
ret = [at copy]; // << give them a copy if cookie is not threadsafe
}
}
}
return [ret autorelease];
}

@end

更新2

@synchronized 设置对象级锁定。您可以将其视为您的实例独占的递归(或可重入)锁。与其他锁定方法相比,它也相当慢。上面的代码使用了它,它是线程安全的,相当于持有一个递归锁,并在@synchronized边界处加锁和解锁。

@interface MONCookie : NSObject <NSCopying>
{
@private
NSRecursiveLock * lock;
}

@end

@implementation MONCookie

- (id)init
{
self = [super init];
if (nil != self) {
lock = [NSRecursiveLock new];
}
return self;
}

- (void)temperatureDidIncrease
{
// ...
}

- (void)bake
{
// use the same lock for everything
// do not mix @synchronized in some places, and use of the lock
// in others. what you use to protect the data must remain consistent
//
// These are equivalent approaches to protecting your data:

{ // @synchronized:
@synchronized(self) {
[self temperatureDidIncrease];
}
}

{ // using the lock:
[lock lock];
[self temperatureDidIncrease];
[lock unlock];
}
}

@end

关于iphone - Objective-C 中的线程安全单例对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8757068/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com