Create Objective-C literal object like NSString [duplicate] - objective-c

This question already has answers here:
Can the new Clang Objective-C literals be redirected to custom classes?
(2 answers)
Closed 6 years ago.
I want to know if it's possible to create Objective-C literals like NSString, where instead of [[Object alloc] init], and then assigning you can just assign a value to it, such as #"A string".
Obviously NSString is an object because it has methods to manipulate the data in addition, so in theory there should be a way to do it yourself, but I'm not sure where to even go about finding stuff like this.

Objective-C is C. The primitive (what I would call scalar) data types are all numbers and are completely defined by the language; you cannot add to them (though you can rename them using typedef. The corresponding literals, such as 1 and "hello", are also part of C.
Similarly, literals like #"howdy" and #[#"howdy"], though defined by Objective-C rather than C, are part of the language and you cannot change or add to them, as the literal syntax is built into the language.

Related

Can I access an ObjC constant by string name at runtime? [duplicate]

This question already has an answer here:
How do I lookup a string constant at runtime in Objective-C?
(1 answer)
Closed 7 years ago.
I know that Objective-C allows me to refer to selectors by name using #selector(#"name") How can I access the following constant by name at runtime? In other words, I would pass #"CONST_KEY" somewhere and get #"key" back.
const NSString* CONST_KEY = #"key";
I think I can do this by first creating a key-value dictionary and then querying it at runtime, but I'm not sure if there's a better implementation.
To clarify with a specific use case:
I want to use a collection view cell reuse identifier #"CONST_KEY", declared in my storyboard, and to be able to use this identifier to look up the value of CONST_KEY at runtime.
This way I hope to have a single place within my code to modify constants, rather than having to re-assign values in multiple classes. Having the two values linked will allow me to have a single action for all those cells using the CONST_KEY to define the action they are going to do.
Objective C is just a C with added object functionality. So "CONST_KEY" constant name is discarded during compilation. So you have to create your own class or use an NSDictionary to provide "constant_name"->"constant_value" functionality.
You don't need to call a selector to get the constant, you just need to expose it to your other classes. Also the constant should live inside of its relevant class. The method I use is the following.
in the header file right below your import statements (before #interface) declare this:
extern NSString *const CONST_KEY;
In the implementation file in the same place (above #interface and #implementation) declare this:
NSString *const CONST_KEY = #"key";
After you do that, in any class that imports the class where you declared your constant, you will be able to reference it simply with CONST_KEY
E.G.
[someDictionary objectForKey: CONST_KEY];
or
NSLog(#"%#", CONST_KEY);
etc etc – Using this convention is great for type safety. I use it all the time.

Mutable array object types [duplicate]

This question already has answers here:
NSMutableArray - force the array to hold specific object type only
(12 answers)
Closed 9 years ago.
I'm programming on Objective C for the first time, coming from C++ (so far I like
the latter much better!). I have a question regarding mutable arrays, namely I want to create one with the specific type of one of my objects, 'CMParticle', instead of the generic ID type. To access data in my object from my mutable array, I have to cast it as one of my objects each time (which is I believe cumbersome) like so:
rij[0] = ((CMParticle *)particles[*pi]).crds[0] - ((CMParticle *)particles[*pj]).crds[0];
where 'particles' is my mutable array of CMParticle objects. I would rather do this
rij[0] = particles[*pi].crds[0] - particles[*pj].crds[0];
Prior to this I declare my mutable array like so:
particles = [NSMutableArray array];
It would be nice if I could declare this array with my type somehow so I don't have to typecast every time. Is there a way to do this?
What you're trying to do doesn't actually make sense in Objective C.
C++ containers are homogenous, but generic. You can have a vector<CMParticle>, or a vector<int>, and they're different types.
ObjC containers are heterogeneous. You just have an NSArray, and it can hold CMParticle objects, NSNumber objects, or anything else, all mixed up in one big array.
You generally don't need these casts at all. If you want to send a message to my_array[3], just do [my_array[3] doSomething:15]. Just like a higher-level language (Python, Ruby, Smalltalk, Javascript, etc.).
The only problem is that (unlike Python, etc.), there are a few cases where you do need the cast. Most critically (and annoyingly), if you want to access members directly, you have to cast first. This is one of the reasons that ObjC (unlike Python, etc.) encourages you to use #property and/or explicit accessors instead of directly accessing members. (Also, as a more minor annoyance, because variables have declared types, you can't just write tempval = my_array[3];, you have to specify the type, like: CMParticle *tempval = my_array[3].)
Another way to look at this: C++ extends C's static, weak type system to give you a stronger static type system; ObjC instead bolts on a separate dynamic type system (unfortunately leaving the existing C stuff unchanged, which is where the occasional problems come in).
You can pretty easily write your own NSMutableArray subclass that's generic (taking the class at runtime, unlike C++'s compile time, of course) and homogenous, but all that does is add restrictions; the elements will still be id everywhere. The only way around that is to write a custom class for each array: MutableCMParticleArray, MutableNSNumberArray, etc.

Is there any way to get a property's type in Objective-C? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to detect a property return type in Objective-C
Is there any way to get a property's type in Objective-C? I can access the property like this:
objc_property_t* properties = class_copyPropertyList(cl, &count);
And get the name like this:
property_getName(properties[i]);
What I need to do though is get the type. Also, the value will be nil in most cases so I can't just get the value calling object_getClass().
Not in the sense that you seem to be asking — in Objective-C classes are typeless; when dealing with non-C types beyond 'it's a class' the type of properties isn't known at runtime. That's why if you do something silly like the following in a view controller:
[self setValue:#3 forKey:#"view"];
You'll see an exception raised when the controller attempts to send a view message to the NSNumber rather than by the key-value coding mechanisms because you tried to put something that isn't a view into in an inappropriate property.
Parsing property_getAttributes will allow you to go no further than distinguishing the various C literal types from an Objective-C object type.

Why is it a pointer? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
objective c difference between id and void *
why most of the objects we create in iphone are pointers
According to Stanford university course, 2010/2011
Lecture 3
The guy made something strange there (at least for me), which is that
NSString *digit = sender.titlelabel.text;
Why is digit a pointer?
The type of your digit is id, which is just basically just a C pointer to a certain struct. All references to objects in Objective-C have this primitive type, regardless of the Class of the object. So the answer to your question is, unfortunately, because that's the way Objective-C works.
So whether you're declaring an NSString*, or an UITableViewController*, or MyClass*, your variable has type id. This is the primary means by which the language implements polymorphism. So, for example, the following declarations are equivalent:
NSString *digit;
id digit;
And it's true of method prototypes as well. These are equivalent:
-(UITableViewCell *)tableView:(UITableView)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
-(id)tableView:(id)tableView cellForRowAtIndexPath:(id)indexPath;
A variable of type id is not an object itself, it is a pointer to an object. It is the handle with which you manipulate an object. Objective-C does all of the class compatibility work at runtime.
Hope this helps. Any questions?
Updates
That's right: int, float, double, char, void, and the pointer combinations, are all C primitive types. You can and will still use these quite a bit, and they are just what they are in a C program. But Objective-C adds the id type as a way to bridge the gap between the primitive typing of C and the very high-level typing of objects by the Objective-C system. id itself is typedef'd as a pointer to a simple struct in objc.h. At the level of the compiler and the language itself, there really isn't too much meaning to the type. For example, you'll almost never declare an array of ids, certainly never perform any arithmetic with them.
In fact, it's not too far a stretch to say that Objective-C is just plain vanilla C with some added syntax (particularly, the square-bracket notation for method invocation), a few extra primitive types (id, IMP, SEL), and a big runtime library. It's this runtime library that handles all things Object-Oriented.
Anyway, to answer your question, when you're actually programming, you will most often (99% of the time) just use class names to declare your variables - NSString *, NSData *, UITableViewController *, and so on. And the compiler will know what you're talking about, and issue a warning if you write code that clearly tries to put an NSString* where an NSData* is expected. But the actual meaning of those types really exists only at runtime.
I've digressed a little, but I'm not sure where your understanding is failing you, so I thought I'd just explain things a bit. You might want to read Apple's The Objective-C Programming Language to get a feel for the language.
NSString is an Objective-C class and all object references in Objective-C are pointers. I would suggest reading through some of the documentation such as Learning Objective-C A Primer:
Notice the * in the first declaration. In Objective-C, object
references are pointers. If this doesn’t make complete sense to you,
don’t worry—you don’t have to be an expert with pointers to be able to
start programming with Objective-C. You just have to remember to put
the * in front of the variable names for strongly-typed object
declarations. The id type implies a pointer.
It's not a digit, it's the "text" from the label, which is (I'm guessing) a string of integers and such to express the time.
So, all NSString types are declared as pointers in Obj-c.
sender.titlelabel.text;
Returns a NSString *
Remember, it's the same as:
NSString *str = [sender.titlelabel getText];
Because text is too. Or more preceisly, because the getText message returns a pointer.
You can find an intersting about why it has to be a pointer:
NSString and Pointers
I Hope it will help you to understand it in a Objective-C way.

The asterisk in Objective-C object instance declarations: by the Object or by the instance? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What's your preferred pointer declaration style, and why?
In C, why is the asterisk before the variable name, rather than after the type?
What makes more sense - char* string or char *string?
When declaring a new instance of an object in Objective-C, does it make any difference where you put the asterisk?
Is this just a matter of personal preference?
NSString* string = #"";
vs.
NSString *string = #"";
It doesn't make a difference, but there are good reasons to put it in each place:
It makes sense to put it near the class, because that makes it feel like a type: NSString*, a pointer to a string. Sensible.
It makes sense to put it near the variable, because that's what's actually happening: * is dereference. When you dereference your pointer string, you get an NSString. *string is an NSString. Sensible.
You may want to go with the latter because that's the way the compiler is thinking, so: NSString* oneString, anotherString will not work, whereas NSString *oneString, *anotherString is correct.
It's simply a matter of preference. Putting the * next to the type emphasizes that it's part of the type, i.e. "pointer to an NSString". However, this is usually frowned upon, because it ignores the fact that the * associates with the nearest variable name, not the type name. For instance, the following doesn't work:
NSString* a = #"string1", b = #"string2
This is because a is a pointer, but b is not.
Putting the * next to the variable name is, in my opinion, more of a C/C++ convention, because it emphasizes that the * and the variable name together act kind of like a variable.
Personally, I put a space on both sides of the *.
Another question that asked the same thing is here:
Declaring pointers; asterisk on the left or right of the space between the type and name?
It doesnt make the difference wher you put that pointer symbol. If you declare multiple objects in single line, you do it like NSString *str1, *str2. So its more appropriate to put that asterisk close to object. I prefer it close to object instance.