objective-c : will this create a memory leak - objective-c

If I have a code looked like this:
-(void) func {
ObjectA* A = [[ObjectA alloc]init];
[something doSomething:blah andDelegate: A];
}
Assuming the call of doSomething will make a http request call so the delegate will be called only when it received response from the server. In this case, there would be a delay.
Note: something is an instance variable of a class.
If I call 'func' twice, will the first initialized of A be leaked before it received the response on the delegate. Assuming there is a release operation when calling the delegate function when received the responsed.
The reason I thinking of this is because if second initialized of 'A' passed in to something as an delegate before the first delegate finished it's role. Will second initialized of 'A' replaced the first initialized of 'A'?

Yes, if you're not compiling with ARC, you have a leak. You're creating an object with alloc, which means that you own it, and you're not relinquishing that ownership by sending release. This is the core memory management rule for Cocoa.
It may be that the object, something, to which you're passing A, also needs to own A (in fact, it sounds like that is the case). If so, something should send retain to A and then send release when it no longer needs A.
Will second initialized of 'A' replaced the first initialized of 'A'?
Sort of. The name A is only valid inside this method. When you create an object and assign it to A, and then that name goes out of scope, you can't refer to the object anymore. That's what a leak is. When you run this method again, essentially a new name A is created and you assign another object to it.

something and func should be releasing A. something should also retain A when its used.

Related

NSInvocation - How to figure out who the message was directed to from inside forwardInvocation:

Both sourceObject and destinationObject are instances of the SameClass. SameClass is a Singleton. Essentially the same object goes by two different names and has behavior at method level which is different based on that. I have these lines of code:
(there is a symmetry here, I need them to call the same method but in two different places under two different circumstances)
//some code in some place
[singleton1Object increase: 20];
//some code in a completely different place
[singleton2Object increase: 40];
Neither singleton1Object or singleton2Object implement increase: instead they both use it to direct the message each in their respective directions (other objects)
forwardInvocation
- (void)forwardInvocation:(NSInvocation *)anInvocation
{
//determine where the message came from
}
Is there any way to determine which part of the code singleton1Object or singleton2Object initially received increase: and base my decision of where to route, on that, from inside forwardInvocation:?
NOTE: The Singleton send messages to itself he is both the sender and the receiver. He refers to itself by two or more names in code, stored in two of it's variable, he keeps doing this until it gets from method to method to one he does not understand in which case he forwards the message to another object. Where I am in the code, mainly determined by singleton1Object and singleton2Object or some other technique has the clue to where I should forward my messages. Edited the question see edit for more details.
In forwardInvocation, self is the receiver of the message.
The invocation object does not contain information about the initial sender of the message.

NSManagedObject Faulted

I have an NSManagedObject that has some of its properties initialized at the start of the program. When I refer to this object later, it appears to be faulted, and the properties are not accessible. I'm not sure what I need to do.
This is related to a new feature added to a program that has been operating smoothly with core-data in all other ways.
Here is a code snippet where it is initialized as a property value of a singleton. (That singleton is accessible by many parts of my code):
favoritesCollection = [[SearchTerms alloc] initWithEntity:[NSEntityDescription entityForName:#"SearchTerms" inManagedObjectContext:moc] insertIntoManagedObjectContext:moc];
favoritesCollection.keywords = #"Favorites List";
favoritesCollection.isFavoritesCollection = [NSNumber numberWithBool:YES];
favoritesCollection.dateOfSearch = [NSDate NSCExtendedDateWithNaturalLanguageString:#"4000"];
favoritesCollection.pinColorIndex = 0;
[moc save:&error];
NSLog(#"(favoritesCollection) = %#", favoritesCollection);
}
return favoritesCollection;
When I look at favoritesCollection with the NSLog, I see this (I added some newlines to make it easier to read):
(favoritesCollection) =
<SearchTerms: 0x5c28820>
(entity: SearchTerms; id: 0x5a6df90
<x-coredata://3936E19F-C0D0-4587-95B6-AA420F75BF78/SearchTerms/p33> ;
data: {
dateOfSearch = "4000-09-25 12:00:00 -0800";...*more things after this*
After the return, another NSLog shows that contents are intact.
When I refer to this instance later, I can see this in the debugger:
<SearchTerms: 0x5c28820>
(entity: SearchTerms; id: 0x5a6df90
<x-coredata://3936E19F-C0D0-4587-95B6-AA420F75BF78/SearchTerms/p33> ;
data: <fault>)
and that's all.
So I believe that the object is retained (I explicitly retain it where it is returned). I have zombies on and it doesn't look like a zombie.
I have only one managedObjectContext in the program, maintained in the singleton.
So what is happening, and how do I get to the properties that were saved?
There is nothing wrong with your object and I think you might be misinterpreting the meaning of "fault" here.
From Apple's documentation:
"Faulting is a mechanism Core Data employs to reduce your
application’s memory usage..."
Once you try and access any of the object's properties it will hit the database for all of the object's properties.
More details here http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreData/Articles/cdFaultingUniquing.html
Faults are CoreData's way of having loose links to other entities. Just access the values via properties or valueGorKey and you will see them populated just in time.
I'm a little late getting back to this, but I found out that some steps in my program were out of order. Instead of deleting the database contents (something I do at startup every time, for now) and then creating and adding this entity, I had created and added the entity and then deleted the database contents.
The pointer to the favoritesCollection entity is held for the lifetime of the program, so I would have expected it be able to see its contents any time after it was created.
From the Core Data Programming Guide
Fault handling is transparent—you do not have to execute a fetch to
realize a fault. If at some stage a persistent property of a fault
object is accessed, then Core Data automatically retrieves the data
for the object and initializes the object (see NSManagedObject Class
Reference for a list of methods that do not cause faults to fire).
This process is commonly referred to as firing the fault.
Core Data automatically fires faults when necessary (when a persistent
property of a fault is accessed).
From what I can tell by reading the programming guide, seeing faults on relationships (links to other entities) is normal when looking at any particular entity. But seeing faults on the persistent property values is not mentioned. I believe that, in general, if the object is in memory, then its properties should not be faulted, but its relationships may be faulted.
The fact that the favoritesCollection entity was fully faulted (properties and relationships) and the fault did not get resolved revealed a problem. In this case it is consistent with the entity no longer existing in the database.

In Core Data is there any consequence to not saving a newly created NSManagedObject into its MOC?

I am creating a NSManagedObject by using the insertNewObjectForEntityForName convience message on NSEntityDescription.
For example:
Person *per = (Person *)[NSEntityDescription insertNewObjectForEntityForName:#"Person" inManagedObjectContext:managedObjectContext];
I understand that this will return an autoreleased Person object of instance NSManagedObject to me.
I then decide due to error processing that I don't want to continue to save this new object into the Managed Object Context.
Do I need to do anything further or just not save and leave it be dealloc'd by the run loops auto release pool?
Will this leave the MOC in a stable state? Or should I only use insertNewObjectForEntityForName when I know for sure that I'm going to save the object?
You should only really insert the new object when you know you need it and in this case you would need to delete the object otherwise next time the context IS saved, it will also save this new object.
When calling delete object, if the object has not been saved it will be discarded immediately.
Another approach I take is to create the entity will a nil context (you alloc and init the NSManagedObject manually) and then if you need it you can insert it to your context and save, if not, simply release the object and it is removed immediately.
NOTE: when you insert an object into a context IT DOES NOT automatically insert it's child objects on that context so you need to ensure you go through any referenced objects and insert them on the new context also. For simple primitive types this is not required, only for relationships.

difference between nil and released object

I'm new to Objective-C and and I can't understand this. I know that I can send a message to nil (it's so hyped about feature of Objective-C), but I can't send a message to released object, getting an exception in this case, what the difference between them?
nil is the memory address 0. The runtime knows to not do anything when this address is messaged, because it is the predefined nonexistant object address.
However, a deallocated object will a random memory address, because the pointer isn't cleaned up when the formerly valid object is destroyed. Since it is not the prescribed nonexistant object address, the runtime doesn't know that it's invalid, and will try to send it the message. This will usually crash your program right away.
You can avoid this by setting variables to nil once you've released them.
nil is 'pointing to nothing', and its allowed to send a message to nil (nothing).
An object has a address where its data resists. You use this address to send message and release the object. Like this:
id myObject; // Initialized some where else
[myObject release];
and then send it a message like this:
[myObject someMessage]; // At this point myObject != nil. Not allowed
Then you are actually trying to send a message to the address of the now released object. And this is not allowed.
myObject = nil;
[myObject someMessage]; // Allowed

centralizing my objective C app's networking code

I am trying to centralize my app's networking code. Basically, in any of the various places that need information from a server, I create an object serverRequest of my class ServerRequest to get the information. When ServerRequest is done, it needs to send the information back to the calling object. Of course it should work asynchronously -- I don't want my app to grind to a halt while it is waiting.
This return of the information is the tricky part. It seems my options are delegation and notification. As far as I can tell, they both have their issues:
DELEGATION:
I pass myself off as a delegate to the serverRequest object. The problem is that if I am deallocated before the request completes, serverRequest will be messaging a deallocated object and my program will crash. To prevent this, I would have to keep track of all my server requests (there might be more than one) and let them all know in my dealloc method so that I don't get any more messages. All of this is possible, but it sure seems like a pain.
NOTIFICATION:
Seems like a lot of work to pass the information around. I have to add myself as an observer to the notification center, then remove myself when I deallocate. Furthermore, I have to pass into ServerRequest the information of what kind of notification to post when it is done. And I ServerRequest has to shove the received data into an NSDictionary, which I then get it back out of after it is passed.
Both methods ought to work, but they both seem like an awful lot of effort just to have ServerRequest wake up the calling code and pass it an object. I am thinking notification is a bit more flexible, a bit less of a pain, and a bit less likely to cause a crash, but I'm not really happy with either approach. Any feedback would be appreciated. Thanks.
I would go with the list approach. Just have a requestController containing an NSMutableArray that keeps track of all the requests. The advantage of this is that, when your controller gets deallocated, you can do something like [requests makeObjectsPerformSelector: #selector(cancelRequest)] to stop all those requests from hogging the network. It also helps in debugging, because you can actually ask each object what requests it has pending, gauge the performance impact of many pending requests etc. When a request finishes, the request controller can be informed and can remove it from its list with a simple removeObject.
Also, someone has to own your objects. In manually managed memory, ObjC objects can retain themselves, but if you ever want to move to GC, having an array is a much cleaner solution than CFRetaining free-floating objects.
You should not be retaining your delegates. see Checking for a valid delegate object before sending it a message
you can retain the delegate passed in and you would then not be de-allocated until the server request is also finished.
e.g.
#interface ServerRequest : NSObject
{
id delegate;
}
#property (retain) id delegate;
#end
#implementation ServerRequest
#synthesize delegate;
#end
But then you need to avoid releasing the ServerRequest from the other end, or you can make the initiator of the ServerRequest release it when it is itself released and that would take away the problem. To do that
#interface SomeObject : NSObject
{
ServerRequest getsomedata;
}
#property (retain) ServerRequest getsomedata;
#end
- (void)f()
{
[self setGetsomedata:[[ServerRequest alloc] init]];
[[self getsomedata] release]; // take away the refcount from allocating, setting the property will retain
}
I encountered similar problems in the past, but chose a slightly different design (similar to what #uliwitness suggested.
I choose to separate the request (i.e. the actual content) from the delivery system. In your case that would mean the serverRequest holds the content of the request (URL, data, etc.) but doesn't do the actual communication with the server. The delegate for the server request would be a singleton CommLayer class which will actually take care of sending the request, receiving it and notifying delegates about request completion.
So to send a serverRequest you would do call something like [CommLayer sendRequest:serverRequest withDelegate:myDelegate].
Now the CommLayer is the actual class that holds the delegate not the serverRequest, and you can always notify the CommLayer that your class is not valid anymore using something like [CommLayer removeDelegate:myDelegate]
Sure it's more work, but you really get a lot of benefits from this design, to name a few:
Real management of network traffic. You can decide how many open connection you want at once and queue requests.
You can cancel unneeded requests