suppose i have a class Foo and an instance of this class myFoo:
Foo *myFoo;
is there any method "dispalyFooObjectName" that can display the name of the object, for exmample :
NSLog(#"i was called from %s", [myFoo dispalyFooObjectName]);
and the result will be :
i was called from myFoo
In most programming languages objects don't have names. Just because some variable myFoo references your object, doesn't mean that your object is "called" myFoo.
And in most C-based languages variable names are not represented in the final executables at all (except for the names of external symbols).
So the short answer is that there's no way to get to that information.
If you want some "name", then you should add a name field to your Foo type.
you can try this. override -(NSstring*)description method like this
- (NSString*)description {
return [NSString stringWithFormat:#"I'm called from foo"];//You can also print object's properties description here.
}
and use like this
NSLog(#"my Foo object %#",[myFoo description]);
Related
I am currently trying to define a method, that takes a Class as argument, that is a subclass of a specific type. My current implementation is:
- (void)methodThatNeedsAClassOfSpecialTypeAsInput:(Class)inClass {}
Taking NSString as an example base class, I have tried NSString.Class and [NSString class] to specify the arguments class, but
- (void)methodThatNeedsAClassOfSpecialTypeAsInput:([NSString class])inClass { }
does not compile with Parse issue: Expected a type.
So the question is: is is possible to make an Class arguments type explicit?
Or in other words: I want my methods signatures semantic to say: I can take a NSString class, an only a NSString class as argument.
EDIT:
The answer is: No.
You almost had it:
[NSString class]
EDIT (after question updated):
This is how the method is defined and declared:
- (void)methodThatNeedsAClassOfSpecialTypeAsInput:(Class)inClass { }
But it is called like this:
[someObject methodThatNeedsAClassOfSpecialTypeAsInput:[NSString class]];
You got it wrong. Method declaration was right
- (void)methodThatNeedsAClassOfSpecialTypeAsInput:(Class)inClass;
Than, in place you call it
[obj methodThatNeedsAClassOfSpecialTypeAsInput:[NSString class]];
If, in implementation you need to be guarantee, that your inClass is NSString, you can use
if([inClass isSubclassOfClass:[NSString class]]) {
//Do whatever you need
}
So I have something like :
- (void) printString:(NSString *)string
{
NSLog(#"%#", string);
}
NSString *string = #"Blach";
[self printString:string];
Would string be passed in by value or reference? What about something like NSError?
NSError *error = [NSError errorWithDomain:someDomain
code:-101
userInfo:someInfo];
-(NSString *) doSomething:(BOOL) val withError:(NSError **)error {
if(!val)
{
*errorPtr = [NSError errorWithDomain:something
code:-101
userInfo:someInfo];
}
}
You can never refer to an Objective-C object by anything other than a pointer, so for all intents and purposes, everything is pass-by-reference. That said, the actual pointer values are passed by value, just like in C.
Everything of every type in Objective-C is pass-by-value only.
The question is invalid because "objects" are not values in Objective-C and therefore cannot be "passed" -- you cannot have a variable or expression whose value "is an object" (a bare object type is not allowed in the language) -- instead, "objects" must always be manipulated behind pointers to objects. Since "objects" are not values and you cannot "pass" them, it is meaningless to ask about whether they are "pass-by-value" or "pass-by-reference".
Objects are passed by reference. The important distinction, to my mind, is whether the called method has a reference to the same object as the caller or if it has a copy. It has a reference to the same object.
If the object is mutable and the called method mutates it, it affects the object that the caller has, too (because it's the same object).
In the case of an NSError** parameter, it is actually the pointer (not an object) which is being passed by reference. A method with such a parameter can actually modify the caller's pointer, making it point to a different object.
With generics on languages like C# or Java, you can have a factory that returns a result depending on the given type? For example you can tell the factory method to return:
Book
List<Book>
Door
List<Door>
Is it possible to achieve the same thing with objective-c?
Can I somehow tell generateObjects method to return me an array of books?
[self getDataFromWeb:#"SOME_URL" andReturnResultWithType:[Book class]];
// What about an array of Books?
- (id)getDataFromWeb:(NSString*)url andReturnResultWithType:(Class)class
{
// Convert JSON and return result
// Mapping conversion is a class method under each contract (Book, Door, etc)
}
Let's say this is one of my data contracts
#interface Book : JSONContract
#end
#implementation Book
+ (NSDictionary *)dataMapping
{
// returns an NSDictionary with key values
// key values define how JSON is converted to Objects
}
#end
EDIT:
Modified the examples to be more clear
No, it is no possible to say that your array will contain String
But, Yes, it is possible to create String based on a Class definition or even a class name.
Objective-C as "reflection" capabilities like Java, it is called "introspection"
For example, you can create an object based on its class name using this code
NSString* myString = (NSString*)[[NSClassFromString(#"NSString") alloc] init];
NSClassFromString is documented here :
https://developer.apple.com/library/mac/#documentation/cocoa/reference/foundation/miscellaneous/foundation_functions/reference/reference.html
If you want the compiler to check types for you, you can also directly use the Class object, as this
Class stringClass = [NSString class];
NSString* myString = [[stringClass alloc] init];
Yes, NSArray and NSMutableArray store objects of type id, which means you can put whatever you want in there and return it to the user. You just check the parameter passed in to branch your logic for generating the objects you are putting in the array.
Your comment suggests this is for converting JSON? To convert JSON you must have a series of conditions checking if the value looks like a number, string, etc. So you could add a condition that says if the class parameter is NSString class then just assume the JSON value is a string.
I'll provide a simple method and then explain how I see it, if this is incorrect, please let me know and correct me. I feel like I understand 'self' but still doubt my self.
-(NSString *)giveBack {
NSString *string = [NSString stringWithFormat:#"Hi there!"];
return string;
}
-(IBAction)displayIt {
NSString *object = [self giveBack];
[myView setText:object];
}
the "myView" is a UITextView object.
Now as for the 'self'..
I'm basically saying in my -displayIt method that I'm creating a NSString object called 'object' and storing within it a method that returns a string which says "Hi there".
And this method (named 'giveBack') is performed ON the name of my class (whatever I named the project). Is this correct?
No, you are not creating an object called object and then storing a method within it etc. You are creating a variable which can hold a reference to an object and storing within it a reference to an object obtained by calling a method.
[Note: The following assumes you are using automatic memory management (ARC or garbage collection), no mention will be made of reference counts. If you are using manual memoery there is more to consider...]
Adding line numbers to your sample:
1. -(NSString *)giveBack
{
2. NSString *string = [NSString stringWithFormat:#"Hi there!"];
3. return string;
}
4. -(IBAction)displayIt
{
5. NSString *object = [self giveBack];
6. [myView setText:object];
}
Declares giveBack as an instance method of the class, to be invoked it must be called on a particular instance.
The RHS ([NSString stringWithFormat:#"Hi there!"]) calls a class method which creates an object of type NSString and returns a reference, of type NSString *, to that object. The LHS declares a variable (string) which can hold a reference to an NSString object. The assignment (=) stores the reference returned by the RHS into the variable declared by the LHS.
Return the value in string as the result of the method
Declare an instance method called displayIt
RHS: call an instance method (giveBack) on the object instance self - self is a reference to the current object instance when within an instance method (in this case displayIt). LHS: declare a variable, object of type NSString *. Assignment: store the reference to an NSString returned by the method call on the RHS into the variable declared on the LHS.
Call the instance method setText: on the object instance referenced by the variable myView passing it the reference to an NSString found in variable object.
I think, you are generally correct.
But in below mention:
And this method (named 'giveBack') is performed ON the name of my class (whatever I named the project)
I can't understand your meaning.
A class name is just a symbol (that is text for human readers).
Methods of an Objective-C class are indicated by - notation in the beginning of method declaration.
In other words, all method declarations start with - within #implementation CLASS_NAME ... #end block are instance method of CLASS_NAME class.
When we call another instance methods (within a instance method) we use self keyword. Because all Objective C method call must designate target object and, in this case, we are calling ourselves (current CLASS_NAME instance itself). So we use self keyword.
Sorry for my confusing words.. It's harder to explain I thought :-(
you're storing the string returned by 'giveBack', not the method itself. the method is part of the class. 'self' is the instance of the object that you're calling 'giveBack' (and 'displayIt' for that matter) on.
suppose i have a class Foo and an instance of this class myFoo:
Foo *myFoo;
is there any method "dispalyFooObjectName" that can display the name of the object, for exmample :
NSLog(#"i was called from %s", [myFoo dispalyFooObjectName]);
and the result will be :
i was called from myFoo
In most programming languages objects don't have names. Just because some variable myFoo references your object, doesn't mean that your object is "called" myFoo.
And in most C-based languages variable names are not represented in the final executables at all (except for the names of external symbols).
So the short answer is that there's no way to get to that information.
If you want some "name", then you should add a name field to your Foo type.
you can try this. override -(NSstring*)description method like this
- (NSString*)description {
return [NSString stringWithFormat:#"I'm called from foo"];//You can also print object's properties description here.
}
and use like this
NSLog(#"my Foo object %#",[myFoo description]);