财产只是一份声明,允许建筑商、购物商和装饰子(隐蔽的外围变量)。
It does absolutely nothing on its own but allow you to use -[myInstance myProperty]
to get the variable or use -[myInstance setMyProperty:]
to set it (yes, the method name is auto-assigned to -setProperty:
and -property
).
When declaring a property, you have three categories - thread locking, access control, and memory management. You can only pick one of the modifiers for each category and if you do not pick one, it s auto-assigned to one automatically.
@property (<thread locking><access control> <memory management>) id property;
The first category can either be atomic
or nonatomic
. The atomic
modifier forces an @synchronized(myInstance) lock on the variable, to allow thread safety. The nonatomic
does not use a synchronized-block, and is NOT thread safe. If you do not use either, it is automatically set to atomic
.
第二类可以是read only
或readwrite
。 <代码>readwrite modifier允许对财产作修改,并允许自动生成——即财产:方法。 仅限代码> 使用变体时,你不能使用<代码>-序Property:方法。 你们必须利用目标内的内部变量直接确定变量。
The third category can either be assign
, retain
, and copy
. The assign
modifier means the internal object pointer is set to the pointer passed to the -setProperty:
message. The retain
modifier assigns the passed pointer and passes a -retain
to the object.
The copy
modifier does a straight-up clone of the object- a new pointer to a new object at a new address in the memory. This sets the internal object pointer to the copy of the passed object, by calling -copy
on the passed object. The default modifier is assign
, and the compiler will warn you if you do not set the memory management category modifier on an object - because an assign
modifier on an object is frowned upon (unless explicitly declared).
For an example on -copy, look at this:
- (void)setProperty:(GXMyObject *)property {
// This points to the original passed object.
GXMyObject *original = property;
// This points to a copy of the passed object.
CGMyObject *copied = [property copy];
// This points to yet another copy of the passed object-
// Independent of the other copies and original.
_property = [property copy];
// The anotherProperty is now different on this copy
// than on the original and the other copies.
_property.anotherProperty = 4;
// This will prove that they are all individual objects.
NSLog(@"%p, %p, %p", original, copied, _property);
}
有一种任择方法名称声明修改如下:getter = myCustomPropertyGetter
和setter = myCustomPropertySetter:
。 (The colon :
at the end of the setter methods name is required by it denotes that an debate must be adopted).
一半是财产合成器或动力器。 财产申报后(例如myView
) 类似:
www.un.org/Depts/DGACM/index_french.htm *myView;
您可以:确定编组和编组;@synthesize
。 <代码>@dynamic 财产是指在某一类别或主要类别中存在,或者在经营时间可以添加(并非一种不明确的想法,是想到的,可能会造成不合时宜的例外情况)。
第一个实例是,撰写方法说明,希望:
// In Apple s LLVM 3.1 Compiler, instance variables can be added
// within {} below the @implementation as well as the @interface,
// and in private categories (@interface GXMyClass ()) like before.
@implementation GXMyClass {
// The internal object pointer is prefixed with an _ to avoid name confusions.
NSView *_myView;
}
- (NSView *)myView {
return _myView;
}
- (void)setMyView:(NSView *)myView {
_myView = [myView retain];
}
@end
第二个例子是使用<代码>@synthesize实现自动化。 指令:
@implementation GXMyClass
// In the new Apple LLVM 3.1 Clang compiler, the = operator when used
// next to the @synthesize directive declares an internal private
// variable and automatically sets to that variable.
@synthesize myView = _myView;
// The internal variable name is now myOtherView, because we did not use the
// = operator to assign an internal variable name to the property.
@synthesize myOtherView;
@end
在最后一个例子中,也许最令人困惑的是,由于需要使用“动力”指令,你要求增加某种类别或临时方法:
@interface GXMyClass (InternalMethods)
@end
@implementation GXMyClass
// The = assignment operator does not work here.
@dynamic myView;
@end
@implementation GXMyClass (InternalMethods)
- (NSView *)myView {
return [self methodThatReturnsAnNSView];
}
- (void)setMyView:(NSView *)myView {
[self methodThatAcceptsAnNSViewArgument:myView];
}
@end
《<条码>@property宣言》要求上述三项声明之一在场,其本身并不做任何事情。 然而,它允许的是信使(用于确定和获取财产的类似于Java的通道)。
例如,@property (copy) NSString *myName;
可使用<代码>。 反对: 目标 MyName:]。
现在可以使用<代码>米。 ObjectInstance.myName = @"Bob'; and gotten using myObjectInstance.myName
. 利用上述所有概念,可以提出这样的目标:
// The GXBufferQueue is a queue which buffers all requests, till they are read
// asynchronously later. The backing store is an NSMutableArray to which all
// buffer writes are appended to, and from which the first object is pulled and
// returned when the buffer is read to.
@interface GXBufferQueue
@property (nonatomic, readwrite, copy, setter = write:, getter = read) id buffer;
+ (GXBufferQueue *)queue;
@end
@implementation GXBufferQueue {
// This queue is an internal array and is tacked on to the @implementation
// so no others can see it, and it can be marked @private so subclasses cannot
// use it. It is also good code practice to have @interfaces composed of only
// @properties, setters, and getters, rather than expose internal variables.
NSMutableArray *_internalQueue;
}
+ (GXBufferQueue *)queue {
return [[[GXBufferQueue alloc] init] autorelease];
}
- (id)init {
if((self = [super init])) {
_internalQueue = [[NSMutableArray alloc] init];
}
}
- (void)write:(id)buffer {
[_internalQueue addObject:buffer];
}
- (id)read {
if(!(_internalQueue.count > 0)) return nil;
id buffer = [_internalQueue objectAtIndex:0];
[_internalQueue removeObjectAtIndex:0];
return buffer;
}
@end
Note: This code was in no way tested.
Now that you have a GXBufferQueue, all the following works:
GXBufferQueue *queue = [GXBufferQueue queue];
// Option One: using the traditional message syntax:
[queue write:@"This will be now added to the buffer."];
NSLog(@"Now the string written to the queue will be read
and removed from the queue, like a stack pop. ", [queue read]);
// Option Two: using the new dot-syntax accessors:
queue.buffer = @"As clunky as this looks, it works the same as above.";
NSLog(@"These lines work just the same as the ones above: ", queue.buffer);
如你所看到的那样,在财产方面可以做很多事情,与财产相比,可以做很多事情。 如果有任何问题或社会希望我增加/撤销职位,请发表评论!