It's the first i post to stackoverflow although i always check the forum.
I am looking for a conveniant way to know who sent a message in ObjC without sending the pointer as an argument in the method.
Can anyone help?
Thanks in advance!
This is not possible in the general case (messages can be set from places where there is no self, such as the runtime or the main function), and it's impractical even where it might be technically possible, because it would require you to walk the stack and analyze the bytes there.
In practice, you shouldn't need to know the sender in most cases other than action methods. It's normally a sign of a bad design. And in any case, when you need to get a reference to another object, it should be passed as an argument to a method.
EDIT: I just stumbled on this and noticed the comment. In case anyone is wondering, the reason it's often a sign of bad design is because it creates a tight coupling between components that is almost never necessary (again, outside of action methods). Usually you can take either a delegate or a callback block to accomplish the same purpose.
No, this isn't possible without passing in a pointer to the sender of the message, like this:
- (void) someMethod:(id) sender {
}
[obj someMethod:self];
I guess you could use the hash value of the underlying NSObject (if the object is a subclass of NSObject). As an NSUInteger it's going to be the same size as the pointer, though, so not much space savings there.
Why exactly do you not want to use a pointer?
Related
Dumb question on my part, so I apologize for not being able to grasp this.
With an NSArrayController, you can send it a remove: message. If I have objects selected and send it remove:nil, those objects are removed. The docs simply describe the message argument remove:sender where sender is "Typically the object that invoked this method."
Could someone explain (or point me to an explanation) on what sender is or should be used for in this context?
Thank you
You probably do not want to use that. Every action method takes an argument sender for general purpose, even in the concrete case it makes no sense. I. e. you might have one action method for different buttons and decide reading the sender reference, what code to execute.
-remove: (NSArrayController) always removes the selected object(s), even you pass an object reference. It simply does not take care of this parameter. If you want to remove a specific object, use -removeObject:.
In our project, we occasionally get our iPhone app to crash when there is something on the network returns JSON with nil in it. Of course, we do have a helper class, which takes care of problems like that. However, people are error-prone and do call objectForKey on NSDictionary instead of our own stringForKey or dateForKey etc.. Now, there is a class to kill all problems like that, once and for all: https://github.com/nicklockwood/NullSafe
My question is: Is NullSafe is really safe? Because sometimes you do want your program to crash if the logic is wrong and you get NSNull. Just ignoring the problem hides it. The app probably will not crash, but, in some cases, will do something weird.
Now I am leaning towards not using this class and just making sure that our JSON NSDictionaries is filtered of all NSNulls BEFORE we try to parse get the values (It could affect performance though).
What do you guys think?
That class is safe in terms of not crashing the application when you send some message to it. It behaves much like nil value.
This class does not solve bugs! If you may get NSNull you should act as it is there and handle that case.
Once I used such class (also because of JSON), but I put NSLog (or ratcher breakpoint) into the -forwardInvocation: method to see from where and why it was called. I wouldn't use this in production.
You also asked about performance. Not sure what takes more: removing NSNulls from an array or searching all classes for their method signatures ;)
I would like to have a method along the lines of
setData:(SomeClassName *)data inPosition:(NSInteger)position
and in the implementation, check for nil as position. The idea is that if the position is provided, I will use it, and if not, I will allocate it automatically.
The problem is I can't pass either NULL or nil into this without a compiler warning.
I believe I have seen this pattern elsewhere (optional parameters). I think it might have been related to an NSIndexPath.
Should I use an NSNumber as a wrapper? or is there some other secret?
As an aside, I considered using separate methods - setData: and setData:inPosition:. But the problem is that 'data' is a core data created attribute, not a regular ivar, so when I actually want to set the value I would have to remember to send all the KVO messages. For example, inside setData:withPosition, I can't call the standard setData: - it would overwrite any work I did with the position.
Would also be interested in knowing which is the 'better' solution of these two.
#Justin's approach is generally the most appropriate. However, to your question about setData: and KVO, there are several things to note:
KVO notifications are sent automatically as long as the method is named setFoo:. Even if you override setFoo:, KVO will wrap your implementation with the correct KVO notification calls for the property. This is very likely the most magical thing in Cocoa. (I used to be certain it was the most magical thing, but I'm starting to wonder about block variable scoping, and especially how blocks are moved from the stack to the heap; that may be more magical.)
If you need to set a Core Data attribute directly, bypassing KVO and every other piece of possible magic, you can use the primitive accessor. setPrimitiveData: is the underlying method that setData: uses to set the property. You should not override the primitive accessors.
#Justin appears to have deleted his answer. The typical solution here would be to declare setData: and setData:inPosition: (btw, as a reader, I have no idea what "inPosition" means. I hope that it makes sense in context). setData: would call setData:inPosition: applying whatever is necessary to figure out "position."
Using the NSNumber wrapper is pretty standard.
Of course, you could always pass -1, NSNotFound, or define your own n/a value too.
There are three options:
Pass -1 or some such for "no value"
Use an NSNumber wrapper and pass nil for "no value"
Overload
You could try to use the Objective-C optional parameter mechanism, but that requires some sort of sentinel to mark the end of the list, so it's no better than any of the others.
I would like to know witch is the best practice to test if void pointer is actually an objective C object pointer (NSObject*)...
- (id)initWithExecPath:(NSString*)executePath withArgs:(NSArray*)args identifier:(NSString*)identifierString contextInfo:(void*)contextInfo {
// I would like to check here if contextInfo is an NSObject
}
Thanks...
Check out this post from the CocoaWithLove site:
In this post, I look at an approach for testing if an arbitrary
pointer is a pointer to a valid Objective-C object. The result from
the test is not absolutely accurate and can interfere with gdb
debugging if the pointer isn't a valid memory location, so this is not
something you'd want to do often (and certainly not in production
code). But it can be a handy debugging tool for when you're staring
blindly at memory you didn't allocate.
The answer is that no you can't provide a general test for "is an Objective-C object". Any such test would have to examine the internal structure of an object and is therefore fragile by definition. There is also the possibility of being handed a random piece of memory that looks like an Objective-C object but isn't. e.g. a recently deallocated object.
There is no reliable way to determine this. Also, any API that takes a context pointer shouldn't care what it is or what it points to, it shouldn't do anything with it other than pass it back to the caller as context.
Perhaps you are asking the wrong question; what exactly do you want to do once you know it is an NSObject?
I have an object that I'm passing in a method call. Say I'm using a language that only allows you to pass objects by reference, like Java or PHP. If the method makes changes to the object, it will affect the caller. I don't want this to happen. So it seems like I need to make a copy of the object.
My question is: whose responsibility is it to clone the object? The caller, before it calls the method? Or the callee, before it changes the object?
EDIT: Just to clarify, I want this to be part of the contract of this method -- that it never modifies the original object. So it seems like it should be up to the method to make the copy. But then the caller has no protection from a method that doesn't do this properly. I guess that's acceptable -- the only other alternative seems to be to have this built into the language.
Generally, the caller should make the copy if it is concerned about changes. If the caller doesn't care, the method should make the copy if it needs to do something that it knows shouldn't persist.
So you want to do something like
MyObject m = new MyObject();
MyObject n = MyObjectProcessor.process(m);?
It seems simpler to me to do something like
MyObject n = MyObjectProcessor.alter(m.clone());
where it's clear who's doing what to who. You could make the argument that the processor class function should be free of side effects, i.e. it should return a new object any time it's going to change state, but (AFAIK) that's not so consistently followed in OO as opposed to functional programming.
Something like the above is probably harmless, as long as it's clearly named and documented.
We could look at ruby for guidance. They use a ! symbol to indicate that an object is modified in-place. So, salary.add(10000) returns a new object but salary.add!(10000) returns the original object but modified. You could use the same idea in Java or PHP by using a local naming convention.
The caller. Because, sometimes you want to make changes to the objects themselves and other times to a copy.
Although, I consider it a bad practice for callee to modify passed objects (at least in object oriented languages). This can cause many unwanted side effects.
(after your) EDIT: In that case it is callee's responsibility to enforce the contract, so there are two options:
The callee simply does not modify the object
or the callee copies the object and works with the copy afterwards
Depends, is there any reason that the method could be called in the future where you want the change to be seen by the caller? If so then the caller should make the copy. Otherwise the callee should make it. I would say that the second case is probably more common.
If you have the caller clone the object, it gives you the flexibility to not use a copy (by not cloning it first), and also means you don't have to return a new object, you can just operate on the reference passed in.
My first reaction would be that it is the caller's responsibility, but I think it actually depends.
It depends on the contract defined between the two methods. The method that is making changes should explicitly identify that fact and let the caller make the decision. OR, The method that is making the changes should explicitly identify that it will NOT make any changes to the passed object and then it would be responsible for making the copy.
I would say the callee: it simplifies calls and caller won't have to worry for the integrity of the given objects. It is the responsibility of the callee to preserve the integrity.
I assume you would have something like const declaration. This would be compiler enforced and would be more efficient than creating copies of your objects.
I think the caller should make the clone, just to make the naming easier. You can name your method Foo() instead of CloneBarAndFooClone().
Compare:
void RemoveZeroDollarPayments(Order order)
vs.
Order CloneOrderAndRemoveZeroDollarPaymentsFromClone(Order order)
If not changing the object is part of the method contract, the only possibility is having the copy made inside the method. Otherwise you are lying to your client.
The fact that you actually need to modify an object exactly like the one given to you is just an implementation detail that should not put a burden on the caller. In fact, he does not even need to have visibility of that.