Memory management related to void* context in Cocoa - objective-c

There are a number of Foundation classes that allow you to provide a pointer to void that is passed as an argument to a callback function at a later time. For instance, addObserver:forKeyPath:options:context: of NSKeyValueObserving.
Since a pointer to void may not extend NSObject, functions which accept such an argument cannot be expected to retain it. Therefore, your code must look similar to the following:
- (void)sharedInit
{
MyObject *myObject = [[MyObject alloc] init];
[x addObserver:y forKeyPath:#"z" options:0 context:myObject];
// cannot (auto)release myObject here
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
MyObject *myObject = (MyObject *)context;
[myObject release]; // myObject is released here
}
This makes sense, although it seems to violate every principle of Cocoa/Objective-C object ownership. In addition, if you forget to manually manage memory in such a case it often (although not always) results in a EXC_BAD_ACCESS crash. Furthermore, the Xcode analyzer complains.
The reason I am asking this question is because I am writing a network connection library that makes use of the same sort of context pointers in its public API. However, after having had to track down a number of memory management bugs in my own code related to the resulting need for manual memory management, I believe there must be a better way. One solution is to change the types of the context arguments of my API to (id<NSObject>) rather than (void*).
Why do Foundation classes often use (void*) rather than (id<NSObject>)?

MHC is correct about the reasoning. There is no requirement that the object be an NSObject. But you are doing your memory management incorrectly here in any case, as you note.
Rather than leaking an object, and then trying to clean it up later, the common pattern for managing an object in this case is to store it as an ivar of the registering class. Another common pattern is to pass self as the context, making sure to unregister for callbacks during -dealloc.

Because it is not always id. Data could be a C structure, or a Core Foundation object, or even a scalar.

Related

Missing sentinel in method dispatch

I want to create a subclass of NSMutableArray and need to override the -initWithObjects: method.
But How to call [super xxx];?
- (id) initWithObjects:(id)firstObj, ... {
[super initWithObjects:firstObj]; // Error: Missing sentinel in method dispatch
// Error: The result of a delegate init call must be immediately returned or assigned to "self"
}
Thanks.
Then "missing sentinel" message refers to the missing nil termination. In fact, according to font-of-all-knowledge-Wikipedia:
The name of the nil that terminates a variable length list of parameters in Objective-C
also: Sentinel node, an object to represent the end of a data structure
also: Sentinel value, a value used to terminate a loop
also: In network protocols such as Bisync, sentinel values indicate where frames start and end
You can't. As discussed in the documentation for NSArray:
You might want to implement an initializer for your subclass that is
suited to the backing store that the subclass is managing. The NSArray
class does not have a designated initializer, so your initializer need
only invoke the init method of super. The NSArray class adopts the
NSCopying, NSMutableCopying, and NSCoding protocols; if you want
instances of your own custom subclass created from copying or coding,
override the methods in these protocols.
So you can assign self = [super init]; and add the objects from your initialiser to the resulting object. Indeed, because of the way that NSArray is implemented, calling any -initWith… method is likely to return an instance of a different NSArray subclass.
Notice that the documentation also discusses alternatives to subclassing NSArray that may be easier, more reliable or better in some other way.
Subclassing NSArray/NSMutableArray doesn't work like subclassing most classes. NSArray is a class cluster, please see subclassing notes from the NSArray documentation.
Now, for your specific question, subclassing va_list methods is a bit tricky, there are a number of ways to handle this. The 'safest' would be to process your va_list into an NSArray and pass that into another method that dealt with whatever you wanted. The other, slightly less portable, slightly hackier way is to create a new va_list list on the stack to pass through.
id __unsafe_unretained * stack = (typeof(stack))calloc(numOfObjects, sizeof(id));
//filloutStack
[super initWithObjects:*stack, nil];
free(stack);
Subclassing Apples Collection classes isn't that difficult — if you use a tiny trick (see also: cocoawithlove).
A subclass is a "is-a" relationship in object-orientated Design. But there are also "has-a" relationships, i.e. wrappers.
If you would try to create a subclass of NSArray by using a pure is-a relationship, I guess, it would be kind of hard, as you would have to do C-level memory management.
But if you add a has-a relationship — or: create a wrapper — at the same time, you can the subcalssing quite easily: Just make your custom array class have a member of a regular NSArray. Now override its method by forwarding the calls to the member object. I showed this in this post, where I just add objects, that pass a certain test.
But you will see, that I didn't implement the method you talked about correctly, but I raise a error. The reason is: that method is a variadic methods, that has a variable number of objects you can pass in — and to handle this, you have to to a bit of work. cocoawithlove has an great article about it.
For you — if using that has-a trick — it could look like
- (id) initWithObjects:(id)firstObj, ... {
if (self = [super init]) {
_realArray = [[NSMutableArray alloc] initWithCapacity:1];
}
va_list args;
va_start(args, firstObj);
for (id obj = firstObj; obj != nil; obj = va_arg(args, id))
{
[self.realArray addObject:obj];
}
va_end(args);
return self;
}
Try
self = [super initWithObjects:firstObj,nil];

Block gets released whilst in NSDictionary (ARC)

I'm trying to retain a reference to a Block that's been passed in to my class by a method, to call at a later time. I'm having trouble, however, maintaining a reference to it.
The obvious way, I thought, was to add it to an ivar collection, all of which are supposed to maintain strong references to their contents. But when I try to pull it back out, it's nil.
The code is pretty simple:
typedef void (^DataControllerCallback)(id rslt);
#interface DataController : NSObject {
NSMutableArray* queue;
}
- (void) addBlock:(DataControllerCallback)callback;
- (void) functionToBeCalledLater;
#end
#implementation DataController
- (id) init {
self = [super init];
if (self != nil) {
queue = [NSMutableArray new];
}
return self;
}
- (void) addBlock:(DataControllerCallback)callback {
NSDictionary* toAdd = [NSDictionary dictionaryWithObjectsAndKeys:
[callback copy], #"callback",
#"some other data", #"data", nil];
[queue addObject:toAdd];
}
- (void) functionToBeCalledLater {
NSDictionary* dict = [queue lastObject];
NSLog(#"%#", [dict objectForKey:#"data"]; //works
DataControllerCallback callback = [dict objectForKey:#"callback"]; //this is nil
callback(#"an arguemnt"); //EXC_BAD_ACCESS
}
What's happening?
Update: I've tried it with [callback copy] and just callback inserting into the dictionary, neither works.
Update 2: If I just stick my block into an NSMutableSet, as long as I call copy, I'm fine. It works great. But if it's in an NSDictionary, it doesn't.
I've actually tested it by putting a breakpoint right after the NSDict is created and the callback never gets inserted. The description reads clearly "1 key-value pair", not two.
I'm currently getting around this with a specialised class that just acts as a container. The callback property is declared as strong; I don't even need to use copy.
The question still stands, though: why is this happening? Why won't an NSDictionary store a Block? Does it have something to do with the fact that I'm targeting iOS 4.3 and thus ARC must be built in as a static library?
Update 3: Ladies and gentleman: I am an idiot.
The code I presented here was obviously a simplified version of the actual code; most particularly, it was leaving some key/value pairs out of the dictionary.
If you're storing a value in an NSDictionary using [NSDictionary dictionaryWithObjectsAndKeys:], you had better be damn sure one of those values isn't nil.
One of them was.
ICYMI, it was causing an early termination of the argument list. I had a userInfo-type argument being passed into one of the "add to queue" methods, and you could, of course, pass in "nil". Then when I constructed the dictionary, chucking in that argument caused the constructor to think I had terminated the argument list. #"callback" was the last value in the dictionary constructor and it was never being stored.
Contrary to popular mis-conception, ARC does not automatically de-stackify Blocks passed as arguments to methods. It only de-stackify's automatically when a block is returned from a method/function.
I.e. this....
[dict setObject: ^{;} forKey: #"boom"];
... will crash if dict survives beyond the scope and you attempt to use the block (actually, it won't in this case because that is a static block, but that is a compiler detail that you can't rely on).
This is documented here:
How do blocks work in ARC?
Blocks “just work” when you pass blocks up the stack in ARC mode, such
as in a return. You don’t have to call Block Copy any more. You
still need to use [^{} copy] when passing “down” the stack into
arrayWithObjects: and other methods that do a retain.
The return value behavior could be automated because it is always correct to return a heap based block (and always an error to return a stack based block). In the case of a block-as-an-argument, it is impossible to automate the behavior in a way that would be both very efficient and always correct.
The analyzer likely should have warned about this use. If it didn't, file a bug.
(I derped a stack when I meant a heap. Sorry about that.)
The compiler doesn't automate blocks-as-parameters for a few reasons:
unnecessarily copying a block to the heap can be a significant performance penalty
multiple-copies of a block can multiply that performance penalty significantly.
I.e.:
doSomethingSynchronous(aBlock);
doSomethingSynchronous(aBlock);
doSomethingSynchronous(aBlock);
doSomethingSynchronous(aBlock);
If that were to imply four Block_copy() operations and aBlock contained a significant quantity of captured state, that'd be a huge potential hit.
• There are only so many hours in the day and automating the handling of parameters is rife with non-obvious edge cases. If this were handled automatically in the future, it could be done without breaking existing code and, thus, maybe it will be done in the future.
I.e. the compiler could generate:
aBlock = [aBlock copy];
doSomethingSynchronous(aBlock);
doSomethingSynchronous(aBlock);
doSomethingSynchronous(aBlock);
doSomethingSynchronous(aBlock);
[aBlock release];
Not only would this fix the problem of a block-as-param, but it would also only produce one copy of the block across all potential uses.
The question still stands, though: why is this happening? Why won't an
NSDictionary store a Block? Does it have something to do with the fact
that I'm targeting iOS 4.3 and thus ARC must be built in as a static
library?
Something bizarre is going on, then. Coincidentally, I've been using blocks-as-values in an ARC based application in the last week and it is working fine.
Do you have a minimal example handy?

Why shouldn't I use the getter to release a property in objective-c?

I was told by a fellow StackOverflow user that I should not use the getter method when releasing a property:
#property(nonatmic, retain) Type* variable;
#synthesize variable;
// wrong
[self.variable release];
// right
[variable release];
He did not explain in detail why. They appear the same to me. My iOS book said the getter on a property will look like this:
- (id)variable {
return variable;
}
So doesn't this mean [self variable], self.variable, and variable are all the same?
For a retained property with no custom accessor, you can release the object by:
self.variable = nil;
This has the effect of setting the ivar (which may not be called 'variable' if you have only declared properties) to nil and releasing the previous value.
As others have pointed out, either directly releasing the ivar (if available) or using the method above is OK - what you must not do is call release on the variable returned from a getter.
You can optionally write custom getter behavior, which may result in completely different behavior. So, you cannot always assume that [variable release] has the same results as [self.variable release].
As well, you can write custom properties without an exclusive ivar backing them... it can get messy fast if you start releasing objects from references returned by getters!
There may be additional reasons that I'm unaware of...
A typical getter will look more like this:
- (id)variable {
return [[variable retain] autorelease];
}
So if you use [self.variable release] you have an additional retain and autorelease that you don't really need when you just want to release the object and that cause the object to be released later than necessary (when the autorelease pool is drained).
Typically, you would either use self.variable = nil which has the benefit that it also sets the variable to nil (avoiding crashes due to dangling pointers), or [variable release] which is the fastest and may be more appropriate in a dealloc method if your setter has custom logic.
not all getters take this form:
- (id)variable { return variable; }
...that is merely the most primitive form. properties alone should suggest more combinations, which alter the implementation. the primitive accessor above does not account for idioms used in conjunction with memory management, atomicity, or copy semantics. the implementation is also fragile in subclass overrides.
some really brief examples follow; things obviously become more complex in real programs where implementations become considerably more complex.
1) the getter may not return the instance variable. one of several possibilities:
- (NSObject *)a { return [[a copy] autorelease]; }
2) the setter may not retain the instance variable. one of several possibilities:
- (void)setA:(NSObject *)arg
{
...
a = [arg copy];
...
}
3) you end up with memory management implementation throughout your program, which makes it difficult to maintain. the semantics of the class (and how it handles instance variables' ref counting) should be kept to the class, and follow conventions for expected results:
- (void)stuff:(NSString *)arg
{
const bool TheRightWay = false;
if (TheRightWay) {
NSMutableString * string = [arg mutableCopy];
[string appendString:#"2"];
self.a = string;
[string release];
// - or -
NSMutableString * string = [[arg mutableCopy] autorelase];
[string appendString:#"2"];
self.a = string;
}
else {
NSMutableString * string = [arg mutableCopy];
[string appendString:#"2"];
self.a = string;
[self.a release];
}
}
failing to follow these simple rules makes your code hard to maintain and debug and painful to extend.
so the short of it is that you want to make your program easy to maintain. calling release directly on a property requires you to know a lot of context of the inner workings of the class; that's obviously bad and misses strong ideals of good OOD.
it also expects the authors/subclassers/clients to know exactly how the class deviates from convention, which is silly and time consuming when issues arise and you have to relearn all the inner details when issues arise (they will at some point).
those are some trivial examples of how calling release on the result of a property introduces problems. many real world problems are much subtler and difficult to locate.

Composite NSOperation. Is this a bad idea?

For an iOS4.X application I am working on, we often need to perform an HTTP request, then parse the results, and do something with the results, and so on.
For this I created an NSOperation class to allow for composition of NSOperations using an NSOperation queue. Is there any issue with using NSOperationQueues for small things like this. Some have told me that the queues should be a more permanent thing.
I don't expect the nesting to be more than 2 levels deep in our application.
Here's an example of such usage:
#implementation CompositeOperation
- (id)initWithOperations:(NSArray *)operations {
if ((self = [super init])) {
operations_ = [operations retain];
[[operations_ lastObject] addObserver:self forKeyPath:#"isFinished" options:NSKeyValueObservingOptionNew context:nil];
}
return self;
}
-(void)dealloc {
[operations_ release];
[operationQueue_ release];
[super dealloc];
}
- (BOOL)isConcurrent {
return YES;
}
#synthesize isExecuting = isExecuting_;
#synthesize isFinished = isFinished_;
#synthesize operations = operations_;
- (void) start {
if (![self isCancelled]) {
operationQueue_ = [[NSOperationQueue alloc] init];
// TODO: Add code to execute this serially
[operationQueue_ addOperations:operations_ waitUntilFinished:NO];
}
}
- (void)cancel {
if (operationQueue_) {
[operationQueue_ cancelAllOperations];
}
[super cancel];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if ([keyPath isEqualToString:#"isFinished"] && object == [operations_ lastObject]) {
[self setIsFinished:YES];
}
}
#end
Thanks,
Mike
I am the one who thinks it is a very good idea so that I even created library after it: CompositeOperations.
There are two operations: simple operation represented by COSimpleOperation object and composite operation represented by COCompositeOperation object.
Simple operation is a smallest possible unit - to quote documentation:
In a nutshell COSimpleOperation is a NSOperation with a small bit of convenience sugar on top of it. As an operational unit for composite operations it usually corresponds to one networking request or some small focused piece of work.
Composite operation is an operation which consists of sub-operations. To quote #mikelikespie:
The point of this object is to make it so one can represent multiple operations that are logically grouped as one operation.
...which is pretty much another description of Composite Design Pattern from Gang of Four Design Patterns.
Composite operation can be parallel or sequential.
Parallel operations are created just as in the code example in question:
NSArray *operations = #[
operation1, operation2, operation3
]; // each operation is NSOperation <COOperation> *
COCompositeOperation *parallelOperation = [[COCompositeOperation alloc] initWithOperations:operations];
To create sequential operation one should instantiate COCompositeOperation with an object conforming to COSequence protocol:
Sequential composition implies sequential flow: sub-operations are executed serially one after another. Sequencing is achieved via collaboration between COCompositeOperation and arbitrary class conforming to COSequence protocol which is used by composite operation as a delegate who decides what operations are and in which order to run them.
To make this composition of operations possible I needed to put small restriction on operations library works with: aside from being NSOperations both COSimpleOperation and COCompositeOperation also conform to <COOperation> protocol:
This conformance basically means that both operations when finished have 3 possible states:
a non-empty result field indicates success
a non-empty error field indicates failure
both empty result and error fields indicate that operation was cancelled from outside (using -[NSOperation cancel] method).
Operation can never have both result and error fields non-empty!
This convention allows Composite Operations to decide at a certain point whether to continue execution of particular group of operations or to stop it. For operations without a specific result [NSNull null] should be passed as result.
For me the rational behind this library was "just" to be able to represent operations so "that they are logically grouped as one operation". There are libraries that achieve the same kind of a higher-level functionality but at the same time they introduce concepts like: Signals in ReactiveCocoa or Promises like in PromiseKit which I don't really need or I would say do not agree with. I wanted something as simple as possible and based on good old well-known NSOperation/NSOperationQueue infrastructure so that's the point of the whole effort.
P.S. I hope this kind of answer fits the SO at least it corresponds exactly to what #mikelikespie was asking about 4 years ago.

What is Key-Value-Coding and Key-Value-Observing in Objective C?

Can someone explain in simple terms what is Key-Value-Coding and Key-Value-Observing? Please don't provide links to Apple Developer's reference Document. I have gone through them. I expect an explanation in very simple terms.
Key-Value-Coding (KVC) means accessing a property or value using a string.
id someValue = [myObject valueForKeyPath:#"foo.bar.baz"];
Which could be the same as:
id someValue = [[[myObject foo] bar] baz];
Key-Value-Observing (KVO) allows you to observe changes to a property or value.
To observe a property using KVO you would identify to property with a string; i.e., using KVC. Therefore, the observable object must be KVC compliant.
[myObject addObserver:self forKeyPath:#"foo.bar.baz" options:0 context:NULL];
Key Value Coding is simply accessing a property of an object through a string instead of the literal syntax.
// Here is a new instance of an object
Foo *foo = [[Foo alloc] init];
// Accessing a property called someValue with literal syntax:
[foo someValue];
// Accessing the same property with dot notation
foo.someValue;
// Accessing the same property with Key-Value coding:
[foo valueForKey:#"someValue"];
The power of KVC is that you can specify any arbitrary string at runtime (obviously this could be very dangerous too).
Key-value coding allows you to fetch or change a property of an object using a string, at runtime, instead of needing to write code that is compiled to a fixed property from the start:
NSNumber* foo = [myPopup valueForKey: #"selectedItemIndex"];
[myPopup setValue: #15 forKey: #"selectedItemIndex"];
A good example for this is NSTableView on Mac, where you can just set an identifier on every table column that corresponds to your model object's property that it should display, and then your data source just calls -valueForKey:/-setValue:forKey: with the column's identifier as the key and the values pretty much display/set themselves. You just add the right columns to the table view in the XIB.
Key-value observing was added afterwards, and lets you register to be notified about changes made to another object. You register your interest by doing:
void* gMyKVOContext = &gMyKVOContext; // global variable somewhere that guarantees us a unique address that doesn't collide with a subclass's registration for observing the same property
...
[interestingObject addObserver: interestedObject forKeyPath: #"interestingProperty" options: 0 context: gMyKVOContext];
Whenever that property is changed, -observeValueForKeyPath:ofObject:change:context: will be called on the object you specified as the observer. So you'd implement that like:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if( context == gMyKVOContext && [keyPath isEqualToString: #"interestingProperty"] )
{
// Update UI that shows interestingProperty
}
else
[super observeValueForKeyPath: keyPath ofObject: object change: change context: context];
}
The advantage here is that you get called live the moment that other property is changed. Note that objects have to do a little work so these notifications are sent, so not all properties are key-value-observable. Also note that some objects may be in an invalid state if two related properties get changed right after the other: You get notified after the first property has been changed, which now contradicts the second, and only then the second property is changed and you're notified for that. So during that first observer callback, the object may be in a weird state, so be careful how you react to that.
To make a property observable, either use the default #synthesized implementation when you define it, or if you define it yourself, implement the setter like:
-(void) setFoo: (int)inFoo
{
[self willChangeValueForKey: #"foo"];
_foo = inFoo;
[self didChangeValueForKey: #"foo"];
}
Then always go through the setter to change it, don't change _foo directly. If you have related properties that could contradict each other like the above, a good way to avoid this is to always change them both in pairs (you can't use KVC then, though). To do that, implement a combined setter like:
-(void) setFoo: (int)inFoo bar: (int)inBar
{
[self willChangeValueForKey: #"foo"];
[self willChangeValueForKey: #"bar"];
_foo = inFoo;
_bar = inBar;
[self didChangeValueForKey: #"bar"];
[self didChangeValueForKey: #"foo"];
}
That way, both notifications are sent while the properties are in proper states.
Start here.
Key-value coding is a mechanism for
accessing an object’s properties
indirectly, using strings to identify
properties, rather than through
invocation of an accessor method or
accessing them directly through
instance variables.
Objective-C Key Value Coding(KVC) vs Key Value Observing(KVO)
[Swift KVC]
KVC allows you to access to property by String it is enabled for all NSObject successors. It adds a dynamism in the language. You can consider your class as Dictionary(Key-Value). It is an alternative/not direct solution to assign/read/write variables
[valueForKey vs valueForKeyPath]
B *b = [a valueForKeyPath:#"b"];
KVC is used by KVO, as well as CoreData, Cocoa bindings...
KVO allows you to subscribe on value changed. It is working for dynamic dispatch
someClass.observe(\.v, options: .new) { (object, change) in
//logic
}
[KVO example]