English 中文(简体)
目标c. 复制和保留的财产
原标题:Properties in Objective c. copy and retain

我从Apple文件中读到的,保留额将增加1,而释放人数将减少1。 我非常清楚这一点。

但 在复制和保留时,一字被混淆。

让我以正尝试的法典来解释。

财产

   @property(nonatomic, retain) NSMutableString *a;

   @property(nonatomic, copy) NSMutableString *b;


   @synthesize a = _a ,b = _b

   a=[[NSMutableString alloc]initWithString:@"Hello Ankit"];
   NSLog(@"a memory location A - %p", &a );
   b=[[NSMutableString alloc]initWithString:@"Hello Nigam"];
   NSLog(@"a memory location B- %p", &b );
   c= [[NSMutableString alloc]initWithString:@"Ankit Nigam"];
   NSLog(@"a memory location C %p",&c);


NSMutableString *temp =[[NSMutableString alloc]initWithString:@"hey"];

NSLog(@"temp = %@ %p",temp,&temp);
self.b = temp;
NSLog(@"B is now %@ %p",self.b,&b);

self.a = temp;
NSLog(@"A is now %@ %p",self.a,&a);

And i get the output as -- - -

2012-05-10 03:24:34.756 retainCountTest[2655:f803] a memory location A - 0x6d314fc
2012-05-10 03:24:34.757 retainCountTest[2655:f803] a memory location B- 0x6d31500
2012-05-10 03:24:34.764 retainCountTest[2655:f803] a memory location C 0x6d31504
2012-05-10 03:24:34.764 retainCountTest[2655:f803] temp = hey 0xbfffdd04
2012-05-10 03:24:34.764 retainCountTest[2655:f803] B is now hey 0x6d31500
 2012-05-10 03:24:34.765 retainCountTest[2655:f803] A is now hey 0x6d314fc

但是,根据我从Doc那里了解的情况,保留物体必须拥有同样的记忆地址,因为复印件将产生一个有不同记忆地点的新物体。

在将原木改为——

self.b = temp;
NSLog(@"B is now %@ %p",self.b,&_b);

self.a = temp;
NSLog(@"A is now %@ %p",self.a,&_a);
It return me a complete different memory location for both the object.

2012-05-10 03:28:49.905 retainCountTest[2688:f803] a memory location A - 0x6d4a4ac
2012-05-10 03:28:49.906 retainCountTest[2688:f803] a memory location B- 0x6d4a4b0
2012-05-10 03:28:49.907 retainCountTest[2688:f803] a memory location C 0x6d4a4b4
2012-05-10 03:28:49.907 retainCountTest[2688:f803] temp = hey 0xbfffdd04
2012-05-10 03:28:49.908 retainCountTest[2688:f803] B is now hey 0x6d4a4c0
2012-05-10 03:28:49.908 retainCountTest[2688:f803] a is now hey 0x6d4a4bc

我能帮助我了解这些保留和复制的完整概念。 这也是我为什么要取得这些意外结果的原因。

感谢很多。

最佳回答

财产只是一份声明,允许建筑商、购物商和装饰子(隐蔽的外围变量)。

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 onlyreadwrite。 <代码>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 = myCustomPropertyGettersetter = 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);

如你所看到的那样,在财产方面可以做很多事情,与财产相比,可以做很多事情。 如果有任何问题或社会希望我增加/撤销职位,请发表评论!

问题回答

是的,retainCount<>/code> 是无用的,不称呼,假定copy将永远退回新的案例是不正确的。

如果发送了<代码> copy,则通常会执行:

- copy { return [self retain]; }

I.e. there is no need to make an actual copy since the contents can t change.

Of course, since you are mucking about with static, compiled into the binary, strings, the implementation is likely closer to:

- retain { return self; }
- copy { return self; }
- (void)release { ; }
- (void)dealloc { ; }

或许——以上所述都是执行细节,随时可能发生变化。 但底线是,上述所有合同都符合保留/延期/复印/etc合同。





相关问题
Code sign Error

I have created a new iPhone application.I have two mach machines. I have created the certificate for running application in iPhone in one mac. Can I use the other mac for running the application in ...

ABPersonViewController Usage for displaying contact

Created a View based Project and added a contact to the AddressBook using ABAddressBookRef,ABRecordRef now i wanted to display the added contact ABPersonViewController is the method but how to use in ...

将音频Clips从Peter改为服务器

我不禁要问,那里是否有任何实例表明从Peit向服务器发送音响。 I m不关心电话或SIP风格的解决办法,只是一个简单的袖珍流程......

• 如何将搜查线重新定位?

我正试图把图像放在搜索条左边。 但是,问题始于这里,搜索条线不能重新布署。

热门标签