Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I'm a totally new to Objective C programming and just need to check how would I implement something I find on the Mac Developer Library.
For example I found this code in the Mac Developer Library:
- (BOOL)containsObject:(id)anObject
Are the steps I need to implement this method?
in the .h file add
-(BOOL)containsObject:(id)anObject;
then in the .m file implement it like this;
- (BOOL)containsObject:(id)anObject
{
//What do I place here to search my array with the objects?
return YES;
}
Can someone help me with an example how I would search an array of numbers and use this method?
This is my array:
NSArray *first;
first = [NSArray arrayWithObjects:1,2,3,4,5, nil];
Do you mean "implement" - as in write your own version - or "use"? You seem to start with the former and end with the latter...
How do you use it? Well taking your example, corrected:
NSArray *first = [NSArray arrayWithObjects:#1, #2, #3, #4,# 5, nil];
The #1 etc. is a shorthand to create an NSNumber object - you can only put object references and not primitive values into an NSArray. The shorthand effectively expands to [NSNumber numberWithInt:1] etc.
Now to use containsObject::
BOOL containsTheAnswerToEverything = [first containsObject:#42];
This will set the BOOL variable to YES if the array contains an NSNumber representing 42, and NO otherwise.
How do you implement it? You examine each element of your array in a loop comparing each to the object you are looking for, same algorithm you would use in C (which it seems you know).
If you are asking how to define a class, then you should read up on Objective-C, but your point 2 is the correct outline.
HTH
In respect to the first question, you can do just that. An example to give you a better visual understanding would be this:
YourClassName.h
#import <Foundation/Foundation.h>
#interface YourClassName : Subclass //replace subclass with something like NSObject or whatever you need
{
}
- (BOOL)containsObject:(id)anObject;
#end
and...
YourClassName.m
#import "YourClassName.h"
#implementation YourClassName
- (BOOL)containsObject:(id)anObject
{
//Insert function body here
}
#end
As for your second question, I am not really very familiar with using NSArray or loading it using that strange function. My advice would be using (NSArray)anObject instead of (id)anObject as you can load the array directly into your function and create your search parameters there. I'm not sure exactly what object you are looking for in terms of containsObject. Are you seeing if it contains the number? If the value contains the array? specify it a bit and I may be able to dig up a better answer for you
EDIT:
It occurred to me that you are probably just looking for the number inside of the array seeing as you are newer to Objective-C. To accomplish what you want you have a couple options. Both require the change of your function. The first would be just changing the function to this:
- (BOOL)containsObject:(int)object fromArray:(int*)array length:(int)length;
In YourClassName.h. Now you can always change your parameters to different data types but this will work for your integers. You can also do this without the length parameter but I figure it saves us some code (personal preference). And in the .m file:
- (BOOL)containsObject;(int)object fromArray:(int*)array length:(int)length
{
for(int i = 0; i <= length; i++)
{
if (array[i] == object)
{
return YES;
}
}
return NO;
}
second would be just without the length option and a bit more code
Related
I have a field:
#interface SomeClass : NSObject
#property(nonatomic, nullable) BOOL questionCreated;
#property(nonatomic, nullable) NSString question;
If I create a setter for question like:
-(void)setQuestion:(NSString)question {
_question = question;
_questionCreated = YES;
}
And then in another file suppose I have an instance of SomeClass called someClassInstance.
If I do something like:
someClassInstance.question = "manually set question"
to my surprise I see that someClassInstance.questionCreated now also has the value YES, which makes me believe it calls the setter directly if I do someClassInstance.question. Why is this and how I can forcefully only set one of the field?
This line of code:
someClassInstance.question = #"manually set question";
is the same as this line of code:
[someClassInstance setQuestion:#"manually set question"];
And by "the same," I mean the former is converted into the latter at compile time. This is what "dot notation" means in Objective-C.
(Side note: when this syntax was added to ObjC in 2007 it was pretty controversial, specifically because it causes the kinds of confusion that you've run into. I was not a fan at the time. Like most folks, however, I've grown very accustomed to the sugar and it is easier to type, so you get used to it. But your confusion is not surprising.)
As a rule, external objects should not be concerned about the internal details of the setter. If they are, something is incorrectly designed (I would probably rename setQuestion to something else).
But another approach is to provide a direct setter. This is most often prefixed "primitive" like:
- (void)setPrimitiveQuestion:(NSString *)question {
_question = question;
}
And then you build setQuestion on top of that:
- (void)setQuestion:(NSString *)question {
[self setPrimitiveQuestion: question];
self.questionCreated = #YES;
}
To your actual question, yes it is possible to do exactly what you're suggesting. It is generally bad form, but if you really need it you can reach in and modify ivars directly:
someClassInstance->_question = #"...";
But don't do this unless you really know what you're doing.
for now i am creating my NSMutableArray using:
#define ARRAY_OF_ORDER_SOURCE [NSArray arrayWithObjects:DICTIONARY_OF_ORDER_SOURCE_ALL,DICTIONARY_OF_ORDER_SOURCE_ECOMMERCE,DICTIONARY_OF_ORDER_SOURCE_PHYSICAL,DICTIONARY_OF_ORDER_SOURCE_INVOICE,DICTIONARY_OF_ORDER_SOURCE_RECURRING,DICTIONARY_OF_ORDER_SOURCE_SALESVU,DICTIONARY_OF_ORDER_SOURCE_RESERVATION,nil]
i want to do some thing like:
if(somethingIstrue)
[ARRAY_OF_ORDER_SOURCE addObject:DICTIONARY_OF_ORDER_SOURCE_ALL]
if(somethingElseIstrue)
[ARRAY_OF_ORDER_SOURCE addObject:DICTIONARY_OF_ORDER_SOURCE_ECOMMERCE]
i am doing this as i need this array in my whole project, i have this in constant.h file.
how can i acheive this using macro??
Thanks.
If you really want to have a macro for this you can have a multiline macro and placed there the logic you want. It is not totally clear to me what you want to achieve but instead of macro I would prefer to have a category on NSMutableArray returning the array or some kind of Util class doing so.
There are numerous things wrong with your question. For starters, you claim you are creating an NSMutableArray, but you are in actuality creating an NSArray. You then try to addObject on the immutable array, which you cannot do.
In your line (note I modified it to add a comment):
if(somethingIstrue) {
// The NSArray isn't assigned to anything and tries to addObject to an NSArray
[ARRAY_OF_ORDER_SOURCE addObject:DICTIONARY_OF_ORDER_SOURCE_ALL]
}
you are not assigning the array to anything (as I already noted it won't work because it is trying to add to an NSArray).
I think you want to do something like:
NSMutableArray *orderedSource = [NSMutableArray array];
if (somethingIsTrue) {
[orderedSource addObject:addObject:DICTIONARY_OF_ORDER_SOURCE_ALL];
}
if (somethingElseIsTrue) {
[orderedSource addObject:addObject:DICTIONARY_OF_ORDER_SOURCE_ECOMMERCE];
}
The question you have to ask yourself is why do you insist on using a macro? You have no real design/approach here, which is why your ideas are coming across as scattered.
If you need to consistently create an array based on a set of constraints, one approach would be to create a class which can vend for you the array you want based on criteria. Or you can just do it where you need to using the approach above.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I want to ask that what is that id? I don't understand what this id is. I got this code from a book and it says a generic type that's used to refer to any kind of object. Can anyone help me with this? I read it few times. Still can't get it.
void drawShapes (id shapes[], int count){
for (int i = 0; i < count; i++) {
id shape = shapes[i];
[shape draw];
}
} // drawShapes
id is an alias for an unknown Objective-C object. It can be used to declare any Objective-C object value.
In the example you have it is using an id rather than a specific class so that the code is not dependent on the class of shape.
Strictly speaking id is defined as a pointer to an objc_object struct.
typedef struct objc_object {
Class isa;
} *id;
In practical terms this means any Objective-C object.
However don't confuse this with NSObject *. While in many cases the equivalence may hold, there are classes which do not descend from NSObject but are still valid Objective-C objects (and therefore whose type can be id). One notable example is NSProxy.
In the code you posted, the id stands for the type of items that will be stored in a C static Array. In particular, the id type indicates any Objective-C object.
Anyway, I would not recommend to use C static arrays in Objective-C to contains objects of unknown type, when you can achieve the same result by using an instance of NSArray.
id means "a reference to some random Objective-C object of unknown class" an example is when you make an at property for a uibutton sometimes it will come up as id but setting it as uibutton will help xcode fill in blanks for you while your typing because now xcode knows exactly what this object is. in your situation shape could be a string or a number or something else if you were just looking at that line of code though passing anything into it could give another line a error later on.
I'm doing a video tutorial on iPhone programming, it's a very simple calculator app. At one point I declare the following method::
- (NSString*)calculate:(NSString*)operation withNumber:(NSInteger)number
{
return nil;
}
It's not implemented yet at this point. Then I want to call the method with:
self.display.text = [self calculate:[sender currentTitle] withNumber:[self.display.text intValue]];
Xcode is giving me an error here: 'expected expression'.
What's wrong here? And what is withNumber in the method? I would understand
- (NSString*)calculate :(NSString*)operation :(NSInteger)number;
Thats a method that takes a string and an int as parameters and returns a String. I don't get what withNumber does here.
OK, for it to work, you will need to remove the unnecessary spaces :
- (NSString*)calculate:(NSString*)operation withNumber:(NSInteger)number{
...
}
and on calling the method too of course.
As to 'what is withNumber ? ' : this is the way multi-input method look like in Objective-C, the name of the method does not precede the arguments. The method is actually named calculate:withNumber: in the runtime system
I strongly recommend reading some beginner's guide
You could do - (NSString*)calculate:(NSString*)operation :(NSInteger)number and then you will have to call [self calculate:myString :myNumber]; but the vast majority of Objective-C user would not do that : the language gives you the opportunity to clarify your code and specify what arguments is what : take that opportunity.
I like to create an instance of a custom class by passing it a value that upon init will help set it up. I've overridden init and actually changed it to:
- (id)initWithValue:(NSInteger *)initialValue;
i'd like to store this value in a property of the instantiated object and use the value to generate the filename of a UIImage that will be associated with it.
My question is how best to go about this in Cocoa/Obj-C. is an NSInteger the best parameter for my needs or would an NSString be better? Or is there another design pattern? I'm not familiar with all the creative methods available to help in this situation. Assume my class properties are:
#interface MyView : UIView {
UIImage *image;
NSInteger value;
If I stick with the NSInteger as a parameter I can easily assign value to it. but then would need to generate "image12.png" from that value (assume NSInteger = 12) to set up my UIImage. Something like "image"+initialValue+".png". Which I believe is verbosely expressed in Obj-C as:
NSString *myValue = #"image";
[myValue stringByAppendingString:[initialValue stringValue]]; //NSInteger may not respond to stringValue?!?
[myValue stringByAppendingString:#".png"]
This is where my understanding of Obj-C breaks down. Feels to me like this should be easier but I'm still confused.
Now if initialValue was an NSString with the value of #"12" maybe it is? then self.value = [initialValue integerValue];
and I could build image with multiple stringByAppendingString calls. Just seems tedious for something so simple in other languages.
What's best way to handle something like this?
Your init method looks fine, and if you're only dealing with integer values, you do want to use NSInteger as opposed to NSString or even NSNumber. The one thing you might want to change is the parameter you're passing should be (NSInteger), not (NSInteger *) - an NSInteger is not an object, but in Objective-C is a primitive type similar to int.
You can build the image name by using NSString's stringWithFormat: selector, as such:
NSInteger myInteger = 12;
NSString *imageString = [NSString stringWithFormat:#"image%d.png", myInteger];
Just to expand on what Tim mentioned, an NSInteger is actually just a #define. On 32-bit architectures, it's equivalent to an int and on 64-bit architectures it's a long.
If you need to treat an integer as an object (to put it in an NSDictionary, for instance), you can wrap it in an instance of NSNumber using numberWithInteger:.
Hope that helps!
One other thing to keep in mind though is that when you're dealing with paths NSString gives you stringByAppendingPathExtension: and stringByAppendingPathComponent:, both of which handle things like trailing slashes better than if you just use stringByAppendingString:.
If you describe a little more about what this object does and what kind of images it's loading I might be able to offer some advice if I can think of a better way of creating the filenames, instead of just passing a number around.