Properties in Objective c. copy and save

What I read from holding an apple document will increase the number of deductions by 1, and the output will decrease by 1. This is very clear to me.

But in the case of copying and saving, I'm a little confused.

Let me explain the code I'm trying to do.

property ---

@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 

But, as I understand from the document, the save object must have the same memory address, where a new object with a different memory cell will be created as a copy object.

Again, when I change magazines to ---

 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 

Can someone help me figure out the full concept of these hold and copy. Also why am I getting these unexpected results.

Many thanks.

+4
source share
2 answers

A property is just a declaration that allows you to use configuration devices, getters and dot-syntax (interface conjugation).

It does absolutely nothing on its own, but allows you to use -[myInstance myProperty] to get the variable or use -[myInstance setMyProperty:] to set it (yes, the method name is automatically assigned to -setProperty: and -property ).

When declaring a property, you have three categories: thread blocking, access control, and memory management. You can select only one of the modifiers for each category, and if you have not selected one, it is automatically assigned to one automatically.

@property (<thread locking>, <access control>, <memory management>) id property;

The first category may be atomic or nonatomic . The atomic modifier causes @synchronized (myInstance) to lock the variable to ensure thread safety. nonatomic does not use a synchronized block and is not thread safe. If you do not use it, it is automatically installed on atomic .

The second category can be either readonly or readwrite . The readwrite modifier also allows you to modify the property and allows you to automatically generate the -setProperty: method. When the readonly modifier is used, you cannot use the -setProperty: method. You must use the internal variable from the object to set the variable directly.

The third category may be assign , retain and copy . The assign modifier means that the objectโ€™s internal pointer is set to the pointer passed to the -setProperty: message. The retain modifier assigns the passed pointer and passes the -retain object to the object.

The copy modifier makes a straightforward clone of an object - a new pointer to a new object at a new address in memory. This sets the internal pointer of the object to a copy of the passed object, calling -copy on the passed object. The default modifier is assign , and the compiler will warn you if you do not install the memory management category modifier for the object - because the assign modifier on the object is not approved (unless explicitly declared).

In the -copy example, 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); } 

There is an optional method name declaration modifier and is used as follows: getter = myCustomPropertyGetter and setter = myCustomPropertySetter: (colon : at the end of the setter method name is required because it means that an argument must be passed).

The second half is a property synthesizer or dynamics. Once a property is declared (e.g. myView ) as follows:

@property (nonatomic, retain) NSView *myView;

You either: define the setter and getter yourself; @synthesize setter and getter; @dynamic property is to say that it exists in a category or in the main class or can be added at runtime (this is not a fun idea, mind you, and may lead to incorrect runtime exceptions).

In the first example, writing the methods themselves, will look like this:

 // In Apple 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 

The second example is to auto-synthesize it using the @synthesize directive:

 @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 

The last example is perhaps the most confusing because it requires using the @dynamic directive, you need something like adding a class or runtime:

 @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 

An @property ad requires one of the three ads above to be present - it does nothing by itself. What it resolves, however, is point syntax assemblers (Java-like accessors for setting and getting properties).

For example, @property (copy) NSString *myName; can be obtained using -[myObject myName] and set using -[myObject setMyName:] .

Now it can be set using myObjectInstance.myName = @"Bob"; and get using myObjectInstance.myName . Using all of the above concepts, you can create an object such as this:

 // 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 has not been tested. Now that you have the GXBufferQueue, all of 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); 

As you can see, there are many possibilities with properties and much more that can be done with them than just declaring a variable. If you have any questions or anything, the community will want me to add / fix in / in the message, please leave a comment !: D

+16
source

Yes, retainCount useless โ€” donโ€™t call it โ€” and assuming copy always returns a new instance is incorrect.

If an immutable copy object is dispatched, it is usually implemented as:

 - copy { return [self retain]; } 

those. there is no need to make an actual copy, as the contents cannot be modified.

Of course, since you are dumping static information compiled into binary strings, the implementation is most likely closer to:

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

Perhaps all of the implementation details listed above are subject to change at any time. The bottom line is that all of the above fulfills the contract of conservation / release / copy / etc ...

+4
source

Source: https://habr.com/ru/post/1411643/


All Articles