2

我想知道以下是否是读取和复制可能被另一个线程锁定的对象的最佳方法?

-(NSObject*) getCopyOfActiveObjectsOfType:(Class) objectClass
{
    NSMutableArray* copy = [NSMutableArray arrayWithArray:[self.activeObjects objectForKey:objectClass]];

    return copy;
}

我有几种方法,如下所示,可以锁定相关对象以向数组添加或删除对象。

-(void) addObject:(NSObject *)object toPoolOfObjects:(NSMutableDictionary*) objects
{
    Class objectClass = [object class];
    @synchronized (objects)
    {
        NSMutableArray* objectArray = [objects objectForKey:objectClass];

        if(objectArray == nil)
        {
            objectArray = [[[NSMutableArray alloc] init] autorelease];
            [objects setObject:objectArray forKey:objectClass];
        }
        [objectArray addObject:object];
    }

}
4

1 回答 1

0

Using the @synchronize method or equivalent in alternate languages:

  • if your instance is accessed from multiple threads and it is not immutable, you will require synchronization blocks around all methods accessing state that can be be mutated
    • your object is immutable if none of the accessors / methods change the internal state of the object.

You are using standard NSMutableArray / NSMutableDictionary primitives for state, however these are not thread safe and therefore require locks when shared across threads. Without knowing the access vs update frequency for your API and it's consumers, it is difficult to recommend a specific solution.

If your API is mostly reads, you could get away with the following solution, which implements a copy on write. Though as always, you must profile to determine if the solution meets your performance requirements.

- (NSArray *)getActiveObjectsOfType:(Class)objectClass {
    @synchronize(self.activeObjects) {
        return [self.activeObjects objectForKey:objectClass];
    }
}

- (void)addObject:(NSObject *)object {
    Class objectClass = [object class];

    // synchronize access to activeObjects
    @synchronize(self.activeObjects) {
        NSArray *existingArray = [[[self.activeObjects objectForKey:objectClass] retain] autorelease];

        NSMutableArray *newArray;
        if (existingArray) {
            newArray = [NSMutableArray arrayWithArray:existingArray];
        } else {
            newArray = [NSMutableArray array];
        }

        [newArray addObject:object];

        [self.activeObjects setObject:newArray forKey:objectClass];
    }
}

What is important to note with this solution is the NSArray returned by getActiveObjectsOfType is immutable.

于 2011-11-15T17:39:51.930 回答