One, thread safety variable control show hidden loading box
Problem Description:
The same page has two asynchronous network requests, the first request starts, loading rotation, the second request starts loading rotation, the first end, loading stop rotation, but then the second request is not over, then the loading is over, so the problem comes.
Solution:
Second, the problems arising from the above problems:
1. #import <libkern/OSAtomic.h>
This passage is copied from the Internet, summed up the role of atomic operations. However, the osbase.h file mentioned in the article cannot be found. This file may not be in my Lib because of a version upgrade.
The atomic manipulation functions on the IOS platform start with osatomic and include the header file <libkern/OSBase.h>. Different threads if you operate on the same variable through an atomic manipulation function, you can ensure that the operation of one thread does not affect the other line range operations on this variable, because these operations are atomic. Because atomic operations can only operate on built-in types, the threads that can synchronize atomic operations can only be in the address space of the same process.
Reprint please explain below: Thank you.
Click to open link ( http://blog.csdn.net/a21064346/article/details/8076972 )
Singleton mode 1:
- + (Abaddressbook *) Sharedaddressbook
- {
- Static Abaddressbook * volatile __shared = nil;
- if (__shared = = nil)
- {
- Abaddressbook * tmp = [[Abaddressbook alloc] init];
- if (Osatomiccompareandswapptr (Nil, tmp, (void * volatile *) &__shared) = = false )
- [TMP release];
- }
- return (__shared);
- }
The above section of code is to create a abaddressbook Singleton, in order to ensure that when calling Shareaddressbook , There is only one memory and the memory address is unique (that is, you are afraid of other threads accessing this function while accessing this singleton)
The effect of volatile is that each acquisition of a number of ways is worth reading directly from memory.
Singleton mode 2:
- + (Ilscmpersistencemanage *) sharedinstance {
- @synchronized ([Ilscmpersistencemanage class]) {
- if (__sharedinstance) {
- return __sharedinstance;
- }
- __sharedinstance = [[Ilscmpersistencemanage alloc] init];
- return __sharedinstance;
- }
- }
The difference:
The former: The bottom of the more regional data, the protection of the singleton from a deeper layer, and not just the pointer, but other data formats. And it does not block the access of other threads to the function.
The latter: lock, the execution efficiency of the code is lower than the former. If it is used in other data, and the data is updated quickly, then the efficiency is very poor.
Reference and study:
1, http://southpeak.github.io/blog/2014/10/17/osatomicyuan-zi-cao-zuo/
2, http://www.cocoachina.com/industry/20130821/6842.html
3,http://southpeak.github.io/blog/2014/10/25/objective-c-runtime-yun-xing-shi-zhi-lei-yu-dui-xiang/
2. Osatomic vs Osatomicbarrier
On Intel and uniprocessor platforms, it doesn ' t matter.
For multiprocessor PPC systems, should all use the barrier variety of functions, unless the atomic store affects no Data Other than the atomic variable.
The following would not be OK:
data_structure[y].data++;
OSAtomicIncrement32 (y);
You must use a barrier here, because and other threads the see data_structure as out of date.
However, if you are using a atomic variable for some purpose where it stands alone, your may omit the barrier:
Y is not used to access any other data
OSAtomicIncrement32 (y);
Fine, as long as the value of Y does not affect the variable of any shared data structure.
Essentially, it ' s a cache flush. You can always safely use the barrier functions, but in some cases, you may be able to improve performance by not using th e barrier functions, such as if Y is not used relative to a data structure. There is probably not many cases where can I use the functions without the barrier.
3. int int32_t int64_t
These things are caused by cross-platform programming;
The type of data, in particular int , is different in length under the platform of different bits of machine. The C99 standard does not specify the length size of the specific data type, only the level. To make the comparison: Level Platform Char 1 of bytes 8 bit Short 2 bytes in a bit int 2 bytes in a bit A long 4 bytes pointer 2 bytes
Level Platform Char 1 of bytes 8 bit Short 2 bytes in a bit int 4 bytes A long 4 bytes A long long 8 bytes pointer 4 bytes
Position Platform Char 1 bytes Short 2 bytes int 4 bytes A long 8 bytes (difference) A long long 8 bytes pointer 8 bytes (difference)
Second, programming considerations In order to ensure the universality of the platform, the program should try not to use long database type. You can use a fixed-size data type macro definition: typedef signed CHAR int8_t typedef short INT int16_t; typedef int int32_t; # if __wordsize = = 64 typedef long int int64_t; # Else __extension__ typedef long long int int64_t; #endif
Third, the use of int can also use intptr_t to ensure the universality of the platform, it is compiled on different platforms of different lengths, but are standard platform length, such as the size of the machine its length is 8 Byte, the size of the machine its length is 4 bytes, defined as follows: #if __wordsize = = 64 typedef long int intptr_t; #else typedef int intptr_t; #endif Use sizeof to calculate the size of the data type as much as possible in programming The above type definitions have a corresponding unsigned type. There are also ssize_t and size_t, respectively , sign size_t and unsigned signed size of computer word size. They are also the word length of the computer, on the four-bit machine is the int type, on the four -bit machine long , in a sense they are equivalent to intptr_t and uintptr_t. They are defined inside the stddef.h. It is important to note that the accept function of the socket is incorrect with size_t on some operating systems because the int* received by accept type, and size_t may be of type long int . Later BSD used sock_t to replace it. |
What data types are uint8_t/uint16_t/uint32_t/uint64_t
In Nesc 's code, you'll see a lot of data types you don't know, such as uint8_t . At first glance, it seems like a new data type, but the C language (nesc is the extension of C ) doesn't seem to have this type of data! How come you are _t again? Many people have this kind of doubt. On the Forum, someone asked: is the type with the end of *_t a long type? Baidu on the search, only to find the answer, then found that the original oneself to C too little mastery.
So what does the _t mean? The specific official answer was not found, but I think there is a close answer. It is a structure callout, which can be understood as an abbreviation of Type/typedef , indicating that it is defined by a typedef , not other data types.
uint8_t,uint16_t,uint32_t , etc. are not new data types, they just use typedef to alias the type, new bottle of wine tricks. However, do not underestimate the typedef, it will have a good role in the maintenance of your code. For example, there is no boolin C , so in a software, some programmers use int, Some programmers use short, it is more chaotic, it is best to use a typedef to define, such as:
typedef char BOOL;
In general, a C project must do some of this work, because you will be involved in cross-platform, different platforms will have different word length, so the use of pre-compilation and typedef can make you the most effective maintenance of your code. For the convenience of users,C99 standard C language hardware for us to define these types, we are assured that the use of it.
according to the POSIX standard, the *_t type corresponding to the generic shaping is:
1 bytes uint8_t
2 bytes uint16_t
4 bytes uint32_t
8 bytes uint64_t
Thread-safe variable control show hidden loading box