[Concurrent] _ [Object-C] _ [Considerations for using NSMutableArray and other non-thread-safe collection classes]
Scenario:
1. During Mac and iOS development, multithreading is generally involved. For example, when a worker thread updates the data model, the main thread displays the interface based on the data model.
For example, the most commonly used NSMutableArray and NSMutableDictionary collections are NOT thread-safe when calling read/write methods, that is, data inconsistency and crash.
2. The solution is to use the @ syncronized () keyword, which is similar to Java.
Test. cpp
/// Main. c // test_sync /// Created by daih on 11/12/15. // Copyright (c) 2015 infoworld. All rights reserved. // # include
# Import
# Include
# Include pthread. h # include
# Include static int THREADCOUNT = 100; // the class to be tested using multiple threads. The class contains the set type attribute and the original type attribute. @ interface MyDevice: NSObject {NSMutableArray * usbArray; // set type NSInteger usbCount; // Original Type} @ property (readonly) NSMutableArray * usbArray; // atomic access can be set for the original type to ensure that dirty data is not read, but the synchronization of arithmetic operations is not guaranteed. // The lock is required. @ property (readwrite, assign, atomic) NSInteger usbCount; @ end @ implementation MyDevice @ synthesize usbArray; @ synthesize usbCount;-(id) init {[super in It]; usbArray = [NSMutableArray new]; usbCount = 0; return self;} @ endstatic MyDevice * gDevice = [MyDevice new]; static int gCount = 0; void * ThreadFunc (void * data) {for (int I = 0; I <10000; ++ I) {// + 1 each time. Note that gDevice is used here. usbCount + 1 is not an atomic operation, so the values of multiple threads may be the same. [gDevice setUsbCount: gDevice. usbCount + 1]; // for multi-threaded access, locks are required to read and write usbArray. @ synchronized (gDevice. usbArray) {[gDevice. usbArray addObject: @ (I)] ;}++ g Count; return NULL;} void TestSyncVariable () {for (int I = 0; I <THREADCOUNT; ++ I) {pthread_t; pthread_create (& t, NULL, ThreadFunc, NULL); pthread_detach (t) ;}} int main (int argc, const char * argv []) {// insert code here... CFShow (CFSTR (Hello, World !)); TestSyncVariable (); while (gCount! = THREADCOUNT) {sleep (2);} std: cout <[gDevice. usbArray count]: <[gDevice. usbArray count] <std: endl; std: cout <gDevice. usbCount: <gDevice. usbCount <std: endl; assert (gDevice. usbCount <= [gDevice. usbArray count]); assert ([gDevice. usbArray count] = THREADCOUNT * 10000); CFShow (CFSTR (Bye, World !)); Return 0 ;}
Output:
Hello, World![gDevice.usbArray count]: 1000000gDevice.usbCount: 999997Bye, World!Program ended with exit code: 0