I think to not really understand what is the best way to upgrade the object_getInstanceVariable used in an old project.
In other word, what is the best thing to use instead of the following instruction?
object_getInstanceVariable(self, [[#"t" stringByAppendingFormat:#"%d", x] UTF8String], (UITextField **)&textField);
You can use valueForKey:, e.g.:
textField = [self valueForKey:[#"t" stringByAppendingFormat:#"%d", x]];
Unlike your code this will find both instance variables and properties.
This will also throw an exception if the variable or property does not exist. This can be addressed by overriding valueForUndefinedKey: on the target class (self in your case).
Related
I'm a kind of self-programmer-made-man, so I'm missing some basic knowledge from time to time.
That's why I'm unable to really define well the topic of my question, because I don't know how to name it and how it works (but I know answer will seem trivial to many of you). When you know what's you're looking for it's a lot easier to find answers.
In objective-c, I can see lines of code like this :
aClassName *myObject = (aClassName *)[NSEntityDescription insertNewObjectForEntityForName:#"aClassName" inManagedObjectContext:app.managedObjectContext];
What's bother me is that (aClass *) part. What's this ?
I know/feel it's related to very basic knowledge but I can't name it so I can't find it.
My guess (and that's how I use it up to now) is that's used for calling class methods (+) but i'm not sure of it and it may be more deep that what I understand.
Thanks for any explanation.
It's a cast, in this case a down cast (even because up casts are implicit).
A cast is an operation that the developer does while writing the code to hint the compiler that a type is narrower than the one the compiler is thinking about.
Think about the following situation:
Class *a = [[Subclass alloc] init];
Subclass *b = a;
(assume that Subclass is a subclass of Class)
This won't compile because a is statically defined with a type which is not contained in Subclass. But the assignment wouldn't create any problem dynamically because a is used to store a Subclass object in practice.
So what you do? You place a cast Subclass *b = (Subclass*)a; to tell the compiler "trust me and ignore typechecking that assignment, I assert that it will be valid a runtime", and you automagically remove the compilation error. Forcing this behaviour of course removes type safety from your code, so you must know what you are doing.
Of course to understand the meaning of a cast in this situation you must at least know about inheritance and objects..
In your specific situation the return type of the method +(id)insertNewObjectForEntityForName:... is id, which is the least specific kind of object in ObjectiveC, it always needs to be casted to something if not stored just like a plain id
It is type cast:
double x = 5.0;
int y = (int)x;
I don't know why it is there in your case, as far as I know that method returns id, so the cast is not necessary (even without it no compiler warning will be generated).
Regarding “where to find such information”: Objective-C/C++ are built upon C and C++ correspondingly, so I'd recommend to learn basics of those languages first.
thats simply mean casting the object to type of the class inside the brackets for example here we cast the defention UITableViewCell to CustomCell
CustomeCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell = (CustomeCell*)[[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
... class methode is a different somthing its function that you can call without need to define an instance of the class ... when you call a instance method you need to do like this
Class *obj = [Class alloc] init];
[obj funtionName];
in Class ethod you just do like this
[Class funtionName];
hope this will be helpful.
I'm diving into iOS programming and I'm having difficulty getting my head around the idea of Dot Notation and Method Notation.
As far as I understand it, Dot Notation can be used to invoke setters/getters on properties and is much more cleaner to write/read. Method Notation is used to send messages to objects to manipulate them etc.
Could someone give me a simple explanation as to why the following two statements are essentially different and one will compile but the other will instead fail due to a syntax error.
- (IBAction)digitPressed:(UIButton *)sender
{
NSString *digit = [sender currentTitle];
self.display.text = [self.display.text stringByAppendingFormat:digit];
self.display.text = self.display.text.stringByAppendingFormat:digit;
}
Thanks.
You're entering into Objective-C development at an interesting time where old syntax is being used with new syntax. Dot syntax is syntactic sugar and there are some cases where you can use it but you should not.
The following is invalid syntax. Anything where you'd use a colon (besides setters or getters), you won't use dot notation.
self.display.text = self.display.text.stringByAppendingFormat:digit;
Also, you would use stringByAppendingString, not stringByAppendingFormat
You use dot notation for accessing variables, not for calling actions that will have effects.
Correct:
self.foo.attributeOfMyClass
Incorrect:
self.foo.downloadSomethingFromAWebsite
Ensuring you always use dot notation for accessing property values and you always use bracket notation (even when you don't have to) for calling action methods, your code will be much clearer upon a glance.
Dot notation is just shorthand for a specific kind of method--namely, accessors. You may use it in the following cases:
When setting a property: foo.bar = 3; is equivalent to [foo setBar:3];.
When requesting a property: in any case except the one above, foo.bar is equivalent to [foo bar].
Dot notation is only shorthand--there is nothing magic about its relationship to properties. You could theoretically use dot notation to send any message that takes no arguments (foo.doSomething), but this would be very very bad style, as dot notation is intended for properties. Also note that if dot notation vs. square brackets is confusing you while you're learning, it's a perfectly valid choice to avoid dot notation altogether. It's just one shortcut you may use for accessors, if you like.
Actually, your second statement is not correct. Objective C way to invoke methods (messages) is using the [instance message] syntax.
As you said, the dot notation is just to call getters and setters on class properties, but not messages, that's why your second statement is not correct. The two lines you may wanted to compare are:
self.display.text = [self.display.text stringByAppendingFormat:digit];
[[self display] setText:[[[self display] text] stringByAppendingFormat:digit]];
Note that the message stringByAppendingFormat has to be called the normal way.
The dot notation is just to write faster and not so many brackets, but it will execute exactly the same instructions once compiled.
Another reason for using selector notation rather than dot notation is due to the dynamic language features in Objective C. As an example, consider the following:
NSString *s = #"Hello World!";
NSLog(#"Length is %d", s.length);
This works as we would expect. However, objects in Objective C may be passed around with type id. Consider the following:
id s = #"Hello World!";
NSLog(#"Length is %d", s.length);
This won't compile, as id doesn't have a property called length. The following will work, however:
id s = #"Hello World!";
NSLog(#"Length is %d", [s length]);
The reason this works is that Objective C knows about NSString, and so knows that there is some object type that responds to the selector length. Of course, if you try the following:
id s = [[UIView alloc] init];
NSLog(#"Length is %d", [s length]);
Your code will compile correctly, but a runtime exception will occur (unrecognized selector sent to instance) as UIView does not have a length selector.
Let's say we have the class Class with the variable variableOne we are going to use both notations.
Dot notation is the purest way to access a variable. It is also the way that bracket notation is most likely doing it behind the scenes. By typing Class.variableOne... variableOne is a part of Class and the "." after the class tells the compiler that it would like to access a part of the class--either a variable or a method.
Bracket notation is uses a method to access the variable. Let's say...
-(int) setVariable:x {
self.variableOne = x;
}
-(int) showVariable {
return self.variableOne
}
So when you're using bracket notation to set the variable [variableOne setVariable:5] or displaying the variable [variableOne showVariable] it calls the appropriate method.
This is a very simple way to think of the difference, I realize another answer has already been accepted but perhaps this answer will explain it for someone who didn't understand another answer.
When your code gets compiled, clang actually first takes all of your dot notation and turns it into method/bracket notation, so self.display and [self display] are exactly the same. Dot notation is actually fairly new as of Objective-C 2.0. It's simply for convenience.
Dot notation can only be used for properties, because doing something like you tried to do (which will not compile) gets cumbersome:
self.display.text.stringByAppendingFormat:digit;
It also wouldn't work for methods that take multiple arguments since you'd need to put spaces between arguments and suddenly the line of code would look awkward and hard to read.
I've many times seen a case where a programmer needs to assign some value (Object or primitive type, does not matter). And let's say this value is an NSString and can be obtained from the following expression
[myObject description]// returns NSString
But for some reason I've seen many people declare another method that itself returns an NSString and executes the above command only. Like:
-(NSString*)getDescription{
return [myObject description];
}
Is this just a matter of preference, or is is there some benefit from it?
Is this just a matter of preference, or is is there some benefit from it?
Those one line wrappers are often used to:
introduce behavior of a method that is meant to be overridden
or (more frequently) to simplify the program. If the method did not exist, you may find the complexity of the program grows. It serves to demonstrate intent, for clarity, documentation, and to minimize redundant implementations (simplifying the program).
There is definitely some "benefit" of creating a method or even better, overriding the "standard" NSObject description method..
If you have a custom NSObject for example and override the +(NSString *)description method you can then return information directly inside that object.
Take for example the following was overwritten in the NSObject we called foo.
+ (NSString *)description {
return #"Hello there";
}
Now, if you ever called [foo description] it would return the string "Hello there".
However, if you just returned description without overwriting the description method, it'd return something like <foo>0x12234 or something.
So yeah, it definitely has a lot of benefit to overriding a custom NSObject description.
Well, in obj-c have the ability of change the class of a declared var. So if I declare myVar as a NSString, is possible to get back later a NSNUmber.
I have this problem now, but I can't find where in my code is the identity swap... exist a way to find it? For example is possible to set a breakpoint where [myVar class] == [NSString class] and when change know it?
You may be confused about the static type of a pointer, and the actual type of the object it points to. Consider this code:
NSString *test = #"test";
NSNumber *notReallyANumber = (NSNumber *)test;
This is valid code, but it didn't "transform" test into an NSNumber. It's still a string, just with an incorrect type on the pointer.
Basically, no, you don't have the ability to change the class of a variable (you do, but it's deep deep magic and almost never occurs).
I'm iterating through some objects and trying to set some properties that, apparently, don't like Key-Value coding. so I'm unable to create a string at runtime to represent the "key".
This line of ViewController won't compile:
[self setValue:offsetX forKeyPath:[NSString stringWithFormat:#"myView%d.center.x", anInt]];
but I can set these properties with dot notation in a ridiculous switch statement:
myView1.center.x = offsetX;
Is there another way to go about this? perhaps create an accessor like myView(i).center.x ? Knowing full well it was going to be futile, i even tried: [NSString stringWithFormat:#"myView%d", anInt].center.x
to no avail...
The reason it wont compile is presumably because offsetX is an int or float, not an NSNumber (it would be helpful to give the compiler error message in your question).
However KVC and setValue:forKeyPath: is very clever and will automatically convert from an NSNumber for you, so use:
[self setValue:[NSNumber numberWithInt:offsetX] forKeyPath:[NSString stringWithFormat:#"myView%d.center.x", anInt]];
(or numberWithFloat as appropriate).