is there a class available to check if an array doesn't contain an object?
I want to do something like
if [(myarray doesntContain #"object")]
is this possible
For NSArray use -containsObject::
if (![myarray containsObject:someObject]) {
// ...
}
I wrote an NSArray category to achieve these negated checks via instance methods, as you had originally requested.. The first is for an array-type set group of objects, the latter for a singular check. These return YES in the case that the array instance DOES NOT contain the passed object or objects. Why? Exclamation marks confuse me.
NSArray+Additions.h
-(BOOL)doesNotContainObjects:(id<NSFastEnumeration>)enumerable;
-(BOOL)doesNotContainObject:(id)object;
NSArray+Additions.m
-(BOOL)doesNotContainObjects:(id<NSFastEnumeration>)enumerable {
for (id x in enumerable) {
if ([self containsObject:x]) return NO; // exists, abort!
}
return YES; // it ain't in there, return TRUE;
}
- (BOOL)doesNotContainObject:(id)object {
if ([self containsObject:object]) return NO; return YES;
}
If you're dealing with an NSArray, your first port of call should probably be the Apple documentation for NSArray, and probably the method containsObject, there's an example in this question.
Related
I want to add object to array only if the array already does not contain that object.
How to do opposite of containsObject method in NSArray ?
Use an NSMutableOrderedSet, whose addObject: method does exactly what you want:
Appends a given object to the mutable ordered set, if it is not already a member.
Here's how I'd do it:
if (![myArray containsObject:objectToAdd]){
[myArray addObject:objectToAdd];
}
More detail here:
https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSArray_Class/NSArray.html
Note that because the containsObject method queries every object in the array there are some performance considerations when using it on larger arrays.
if your object is of NSString* type you can do fast enumeration like this
BOOL found = NO;
for(NSString *object in YourArray)
{
if([object isEqualtoString:#"My text"])
{
found = YES;
}
}
if(!found)
{
//addObject
}
there are many isEqual methods in objective-c for different data types
When comparing top views, the first {} fails to execute. == Equality test fails.
In init, i
[self setCurrentPuzzleView:p1];
And later, i
if ([self currentPuzzleView] == p1) {
NSLog(#"Removing P1 from SuperView");
[p1 removeFromSuperview];
} else {
NSLog(#"Removing P2 from SuperView");
[p2 removeFromSuperview];
}
Is this now how views should be compared? I thought that == is ok for pointer types
if ([self currentPuzzleView] == p1) {
Relationships between the views are set up via the InterfaceBuilder, where each view (p1, p2 etc) is declared as IBOutlet Puzzle1 *p1.
== in Objective-C checks for identity. That is whether two pointers point to the same object.
To test for equality use: [objectA isEqual:objectB]. By default it does the same as == but it can be overridden to have custom equality.
Edit
Having said that and having re-read your question. The two pointers does look as if they are pointing to the same object. Try printing both of the objects you are comparing before you compare them. Also try printing their memory addresses: NSLog(#"Address: %d", &p1); will probably do you.
I would set tag for that view and compare tags.
if(view.tag == 66)
{
// do something
}
else
{
// else do this
}
Your code looks fine to me.
Perhaps self.currentPuzzleview is being modified elsewhere?
Set a breakpoint in the code and check the values, or print the values in your NSLog() call.
How can we identify any particular object is kind of block or not?
for example,
NSSet *set =[NSSet setWithObjects:
#"name1",
#"name2",
[^{ /* ..... some code */ } copy],
nil];
How can we find out which object from set is kind of block?
There is a safer way to determine if something is a block without actually using private api or constructing a class using the private string name:
- (BOOL)isBlock:(id)item {
id block = ^{};
Class blockClass = [block class];
while ([blockClass superclass] != [NSObject class]) {
blockClass = [blockClass superclass];
}
return [item isKindOfClass:blockClass];
}
Wrap your block in a class of your own:
BlockWrapper *blockWrapper = [BlockWrapper wrapperWithBlock:^{ … }];
Check for the type and extract the actual block:
if ([obj isKindOfClass:[BlockWrapper class]]) {
codeBlock = [(BlockWrapper*)obj block];
}
There is no supported way to do this. You must keep track of what objects are blocks, and what their type signatures are.
Do you have a practical use case for a set of mixed strings and blocks?
It's possible, but I wouldn't recommend doing this, because NSBlock is not a public class and its name might change in the future:
if ([obj isKindOfClass:NSClassFromString(#"NSBlock")]) {
NSLog(#"It's a block!");
}
If you only have strings and blocks, just check ![thing isKindOfClass:[NSString class]]. i.e. invert your test.
Likewise, if you have strings, numbers and blocks, check that thing is not a string or a number, and in that case it must (by deduction) be a block. Either that, or your program is incorrect and will crash.
I suppose that ![thing isKindOfClass:[NSObject class]], while not technically correct (you don't have to subclass NSObject), will probably get you want you want.
I want to have a method where I can put as many arguments as I need like the NSArray:
- (id)initWithObjects:(id)firstObj, ... NS_REQUIRES_NIL_TERMINATION;
I can then use:
NSArray *array = [[NSArray alloc] initWithObjects:obj1, obj2, ob3, nil];
I can add as many objects as I want as long as I add 'nil' at the end to tell it I'm done.
My question is how would I know how many arguments were given, and how would I go through them one at a time?
- (void)yourMethod:(id) firstObject, ...
{
id eachObject;
va_list argumentList;
if (firstObject)
{
// do something with firstObject. Remember, it is not part of the variable argument list
[self addObject: firstObject];
va_start(argumentList, firstObject); // scan for arguments after firstObject.
while (eachObject = va_arg(argumentList, id)) // get rest of the objects until nil is found
{
// do something with each object
}
va_end(argumentList);
}
}
I think what you're talking about is implementing a variadic method. This should help: Variable arguments in Objective-C methods
I haven't had experience with these variadic methods (as they're called), but there's some Cocoa functionality to deal with it.
From Apple's Technical Q&A QA1405 (code snippet):
- (void)appendObjects:(id)firstObject, ...
{
id eachObject;
va_list argumentList;
if (firstObject) // The first argument isn't part of the varargs list,
{ // so we'll handle it separately.
[self addObject:firstObject];
va_start(argumentList, firstObject); // Start scanning for arguments after firstObject.
while ((eachObject = va_arg(argumentList, id))) // As many times as we can get an argument of type "id"
{
[self addObject:eachObject]; // that isn't nil, add it to self's contents.
}
va_end(argumentList);
}
}
Copied from http://developer.apple.com/library/mac/#qa/qa2005/qa1405.html
I would try this: http://www.numbergrinder.com/node/35
Apple provides access in their libraries for convenience. The way to know how many elements you have is by iterating over the list until you hit nil.
What I would recommend, however, if you want to pass a variable number of arguments into some method you're writing, just pass an NSArray and iterate over that array.
Hope this helps!
How do I spell a method whose argument can either be an object of a certain type, or nil? You see those all the time in framework classes, but I've just encountered my first instance where it would be useful to create one.
You can always pass nil instead of an object, there's nothing special you need to specify.
- (void) myMethod:(Parameter *)aParameter {
if (aParameter == nil) {
...
} else {
...
}
}
Elsewhere:
[anObject myMethod:foo];
Or:
[anObject myMethod:nil];