http://c.gzl.name/archives/tag/nonatomic
什么是assign,copy,retain之间的区别?
- assign: 简单赋值,不更改索引计数(Reference Counting)。
- copy: 建立一个索引计数为1的对象,然后释放旧对象
- retain:释放旧的对象,将旧对象的值赋予输入对象,再提高输入对象的索引计数为1
retain的实际语法为:
说了那么麻烦,其实接下来的话最重要:
?如果你不懂怎么使用他们,那么就这样 ->
- 使用assign: 对基础数据类型 (NSInteger,CGFloat)和C数据类型(int, float, double, char, 等等)
- 使用copy: 对NSString
- 使用retain: 对其他NSObject和其子类
nonatomic关键字:
atomic是Objc使用的一种线程保护技术,基本上来讲,是防止在写未完成的时候被另外一个线程读取,造成数据错误。而这种机制是耗费系统资源的,所以在iPhone这种小型设备上,如果没有使用多线程间的通讯编程,那么nonatomic是一个非常好的选择。
/
@property是一个属性访问声明,扩号内支持以下几个属性:
1,getter=getterName,setter=setterName,设置setter与getter的方法名
2,readwrite,readonly,设置可供访问级别
2,assign,setter方法直接赋值,不进行任何retain操作,为了解决原类型与环循引用问题
3,retain,setter方法对参数进行release旧值再retain新值,所有实现都是这个顺序(CC上有相关资料)
4,copy,setter方法进行Copy操作,与retain处理流程一样,先旧值release,再Copy出新的对象,retainCount为1。这是为了减少对上下文的依赖而引入的机制。
5,nonatomic,非原子性访问,不加同步,多线程并发访问会提高性能。注意,如果不加此属性,则默认是两个访问方法都为原子型事务访问。锁被加到所属对象实例级(我是这么理解的...)。
@synthesize xxx; 来实现实际代码
/
Property Declaration Attributes
You can decorate a property with attributes by using the form @property(attribute [, attribute2, ...])
. Like methods, properties are scoped to their enclosing interface declaration. For property declarations that use a comma-delimited list of variable names, the property attributes apply to all of the named properties.
If you use the @synthesize
directive to tell the compiler to create the accessor methods (see “Property Implementation Directives”), the code it generates matches the specification given by the keywords. If you implement the accessor methods yourself, you should ensure that it matches the specification (for example, if you specify copy
you must make sure that you do copy the input value in the setter method).
Accessor Method Names
The default names for the getter and setter methods associated with a property are propertyName and set
PropertyName:
respectively—for example, given a property “foo”, the accessors would be foo
and setFoo:
. The following attributes allow you to specify custom names instead. They are both optional and can appear with any other attribute (except for readonly
in the case of setter=
).
-
Specifies the name of the get accessor for the property. The getter must return a type matching the property’s type and take no parameters.
-
Specifies the name of the set accessor for the property. The setter method must take a single parameter of a type matching the property’s type and must return
void
.If you specify that a property is
readonly
and also specify a setter withsetter=
, you get a compiler warning.
getter=getterName
setter=setterName
Typically you should specify accessor method names that are key-value coding compliant (see Key-Value Coding Programming Guide)—a common reason for using the getter
decorator is to adhere to the is
PropertyName convention for Boolean values.
Writability
These attributes specify whether or not a property has an associated set accessor. They are mutually exclusive.
-
Indicates that the property should be treated as read/write. This attribute is the default.
Both a getter and setter method are required in the
@implementation
block. If you use the@synthesize
directive in the implementation block, the getter and setter methods are synthesized. -
Indicates that the property is read-only.
If you specify
readonly
, only a getter method is required in the@implementation
block. If you use the@synthesize
directive in the implementation block, only the getter method is synthesized. Moreover, if you attempt to assign a value using the dot syntax, you get a compiler error.
readwrite
readonly
Setter Semantics
These attributes specify the semantics of a set accessor. They are mutually exclusive.
-
Specifies that there is a strong (owning) relationship to the destination object.
-
Specifies that there is a weak (non-owning) relationship to the destination object.
If the destination object is deallocated, the property value is automatically set to
nil
.(Weak properties are not supported on OS X v10.6 and iOS 4; use
assign
instead.) -
Specifies that a copy of the object should be used for assignment.
The previous value is sent a
release
message.The copy is made by invoking the
copy
method. This attribute is valid only for object types, which must implement theNSCopying
protocol. -
Specifies that the setter uses simple assignment. This attribute is the default.
You use this attribute for scalar types such as
NSInteger
andCGRect
. -
Specifies that
retain
should be invoked on the object upon assignment.The previous value is sent a
release
message.In OS X v10.6 and later, you can use the
__attribute__
keyword to specify that a Core Foundation property should be treated like an Objective-C object for memory management:@property(retain) __attribute__((NSObject)) CFDictionaryRef myDictionary;
strong
weak
copy
assign
retain
Atomicity
You can use this attribute to specify that accessor methods are not atomic. (There is no keyword to denote atomic.)
-
Specifies that accessors are nonatomic. By default, accessors are atomic.
nonatomic
Properties are atomic by default so that synthesized accessors provide robust access to properties in a multithreaded environment—that is, the value returned from the getter or set via the setter is always fully retrieved or set regardless of what other threads are executing concurrently.
If you specify strong
, copy
, or retain
and do not specify nonatomic
, then in a reference-counted environment, a synthesized get accessor for an object property uses a lock and retains and autoreleases the returned value—the implementation will be similar to the following:
[_internal lock]; // lock using an object-level lock |
id result = [[value retain] autorelease]; |
[_internal unlock]; |
return result; |
If you specify nonatomic
, a synthesized accessor for an object property simply returns the value directly.
Markup and Deprecation
Properties support the full range of C-style decorators. Properties can be deprecated and support __attribute__
style markup:
@property CGFloat x |
AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_4; |
@property CGFloat y __attribute__((...)); |
If you want to specify that a property is an outlet (see outlet in iOS, and outlet in OS X), you use the IBOutlet
identifier:
@property (nonatomic, weak) IBOutlet NSButton *myButton; |
IBOutlet
is not, though, a formal part of the list of attributes. For more about declaring outlet properties, see “Nib Files”.
Property Implementation Directives
You can use the @synthesize
and @dynamic
directives in @implementation
blocks to trigger specific compiler actions. Note that neither is required for any given @property
declaration.
Important: If you do not specify either @synthesize
or @dynamic
for a particular property, you must provide a getter and setter (or just a getter in the case of a readonly
property) method implementation for that property. If you do not, the compiler generates a warning.
-
You use the
@synthesize
directive to tell the compiler that it should synthesize the setter and/or getter methods for a property if you do not supply them within the@implementation
block. The@synthesize
directive also synthesizes an appropriate instance variable if it is not otherwise declared.@interface MyClass : NSObject
@property(copy, readwrite) NSString *value;
@end
@implementation MyClass
@synthesize value;
@end
You can use the form
property=ivar
to indicate that a particular instance variable should be used for the property, for example:@synthesize firstName, lastName, age=yearsOld;
This specifies that the accessor methods for
firstName
,lastName
, andage
should be synthesized and that the propertyage
is represented by the instance variableyearsOld
. Other aspects of the synthesized methods are determined by the optional attributes (see “Property Declaration Attributes”).Whether or not you specify the name of the instance variable, the
@synthesize
directive can use an instance variable only from the current class, not a superclass.There are differences in the behavior of accessor synthesis that depend on the runtime (see also “Runtime Difference”):
-
For the legacy runtimes, instance variables must already be declared in the
@interface
block of the current class. If an instance variable of the same name as the property exists, and if its type is compatible with the property’s type, it is used—otherwise, you get a compiler error. -
For the modern runtimes (see “Runtime Versions and Platforms” in Objective-C Runtime Programming Guide), instance variables are synthesized as needed. If an instance variable of the same name already exists, it is used.
-
-
You use the
@dynamic
keyword to tell the compiler that you will fulfill the API contract implied by a property either by providing method implementations directly or at runtime using other mechanisms such as dynamic loading of code or dynamic method resolution. It suppresses the warnings that the compiler would otherwise generate if it can’t find suitable implementations. You should use it only if you know that the methods will be available at runtime.The example shown in Listing 4-3 illustrates using
@dynamic
with a subclass ofNSManagedObject
.@interface MyClass : NSManagedObject
@property(nonatomic, retain) NSString *value;
@end
@implementation MyClass
@dynamic value;
@end
NSManagedObject
is provided by the Core Data framework. A managed object class has a corresponding schema that defines attributes and relationships for the class; at runtime, the Core Data framework generates accessor methods for these as necessary. You therefore typically declare properties for the attributes and relationships, but you don’t have to implement the accessor methods yourself and shouldn’t ask the compiler to do so. If you just declared the property without providing any implementation, however, the compiler would generate a warning. Using@dynamic
suppresses the warning.
@synthesize
@dynamic