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.
Related
Scenario
if (delegate && [delegate respondsToSelector:#selector(aboutTextUpdated:)]) {
[delegate aboutTextUpdated:aboutText];
}
to simplify this kind of checks in my project I created a couple of c functions as below and used them.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
id callSelectorOnDelegateWithObject(SEL selector,NSObject *delegate,id object)
{
if (delegate != nil && [delegate respondsToSelector:selector] == YES)
{
if (object != nil)
{
return [delegate performSelector:selector withObject:object];
}
else
{
return [delegate performSelector:selector];
}
}
return nil;
}
id callSelectorOnDelegate(SEL selector,NSObject *delegate)
{
if (delegate != nil && [delegate respondsToSelector:selector] == YES)
{
return [delegate performSelector:selector];
}
return nil;
}
#pragma clang diagnostic pop
they were called as below
callSelectorOnDelegateWithObject(#selector(aboutTextUpdated:), delegate, aboutText);
Problem
I get EXC_BAD_ACCESS error some times, but not in a reproducible manner. The exception occurred when the c function was called but before executing the first statement. When I replace the function call with actual if statement, then the error never occurs. To meet project deadline I went ahead with that change. But couldn't get this error out of my head.
What is causing the error?
More Background
The project uses ARC, minimum target is iOS 5.0
The project uses AFNetworking 1.* to get data from server, core data to save it in the app and NSNotification for inter app communication
The methods given to perform selector always return void
We would need to see the details of the crash to know more. My best guess is that there are occasional calls to callSelectorOnDelegateWithObject() where object is nil but the method identified by selector actually does take an argument. In that case, you're using just -performSelector:, not -performSelector:withObject:. So, the method receives garbage for its argument.
If some code called callSelectorOnDelegateWithObject() rather than callSelectorOnDelegate() then you should pass the object argument through unconditionally. The caller passing nil does not mean you can drop the argument. The nil probably (or, at least, possibly) is important.
That said, this whole approach doesn't seem like a good idea. I would not find this scheme simpler than the code snippet at the top of your question.
You can simplify that code snippet by not explicitly checking if delegate is non-nil. The -respondsToSelector: check will already return false if delegate is nil, because messaging nil always results in false.
Finally, you should never compare against YES (or TRUE, etc.). You're taking an expression which is already a boolean expression and then making it a compound boolean expression. Let me ask if you would ever write code like the following:
if (([delegate respondsToSelector:selector] == YES) == YES)
...
If you would not write that second == YES (and an infinite sequence of further comparisons to YES), then you should understand why you shouldn't have written the first.
Beyond that, any non-zero value is a true value. YES is only one such value. For any given method which returns a boolean value, you can't be sure that the true value it returns is actually YES as opposed to any other true value.
I would like to know if both of the following solutions for lazy initialization are correct.
I have a class AppContext that is supposed to hold references to other class that should only exist once (Avoiding making every single one of these classes a singleton). Let's say one of these other classes is called ReferencedClass. That being said, I would like to lazy-initialize the references with defaults, in a thread-safe way.
It has been discussed before, and I have read a lot about it, but I am still unsure. Personal preferences aside, what I would like know is: Are these two solutions a correct way to implemented my desired behavior?
Solution 1: Originally I wanted to implement it like this:
// Getter with lazy initialized default value
- (ReferencedClass *)referencedClass {
// Check if nil. If yes, wait for lock and check again after locking.
if (_referencedClass == nil) {
#synchronized(self) {
if (_referencedClass == nil) {
// Prevent _referencedClass pointing to partially initialized objects
ReferencedClass *temp = [[ReferencedClass alloc] init];
_referencedClass = temp;
}
}
}
return _referencedClass;
}
// Setter
- (void)setReferencedClass:(ReferencedClass *)referencedClass {
#synchronized(self) {
_referencedClass = referencedClass;
}
}
Solution 2: Then I decided to go with GCD instead, so I wrote this:
// Getter with lazy initialized default value
- (ReferencedClass *)referencedClass {
// Check if nil. If yes, wait for "lock" and check again after "locking".
if (_referencedClass == nil) {
dispatch_sync(syncDispatchQueue, ^{
if (_referencedClass == nil) {
// Prevent _referencedClass pointing to partially initialized objects
ReferencedClass *temp = [[ReferencedClass alloc] init];
_referencedClass = temp;
}
});
}
return _referencedClass;
}
// Setter
- (void)setReferencedClass:(ReferencedClass *)referencedClass {
dispatch_sync(syncDispatchQueue, ^{
_referencedClass = referencedClass;
});
}
Of course, somewhere (for example in the init-Method) I have initialized the syncDispatchQueue with something like:
syncDispatchQueue = dispatch_queue_create("com.stackoverflow.lazy", NULL);
Is this correct, thread-safe and deadlock-free code? Can I use the double-checked-locking together with the temp-variable? If this double-checked-locking is not safe, would my code in both cases be safe if I removed the outer checks? I guess so, right?
Thanks very much in advance!
[Side note: I am aware of dispatch_once and that some people say that (in contrary to the Apple documentation) it can also be used with instance variables. For now I would like to use one of these two options though. If possible. ]
As far as I understand it, your "double-checked locking" mechanism is not thread-safe,
because the assigment _referencedClass = ... is not atomic. So one thread might read a partially initialized variable in the outer if (_referencedClass == nil) check.
If you remove the outer checks, both versions look OK to me.
You may be interested in
What advantage(s) does dispatch_sync have over #synchronized?
which has a great answer explaining the differences in implementation and performance.
.h
#property (nonatomic,assign) BOOL dontSendDelegate;
.m
#synthesize dontSendDelegate;
- (id) initWithSession:(AVCaptureSession *)aSession outputFileURL:(NSURL
*)anOutputFileURL
{
self = [super init];
if (self != nil)
{
self.dontSendDelegate = NO;
}
return self;
}
if (self.dontSendDelegate == YES)
{
NSLog(#"YES");
}
else
{
NSLog(#"NO");
}
Thats all my code in that class relating to the BOOL.
It always prints YES.
What is it that I'm not understanding? I expect it to always print NO.
EDIT
Used Xcode to search 'dontSendDelegate'
It only appears in the code I've shown. Which is copy and paste.
Changed it to an int and assigned 0 instead of the 'NO' and did the comparison == 1 instead of == YES and it works as you would expect. But I'm still lost as to why BOOL was not working.
Thanks for all the help and discussion about the problem.
When you put the mutable part of an expression (your bool instance variable) before a comparison operator such as ==, sometimes you have a typo where you write = instead, so you set the variable instead of compare it. Look for errors of this type.
Or always put the immutable value first, so in the code you have provided so far you would instead write
if (YES == self.dontSendDelegate)
That way, if you ever type one equal sign instead of two, the compiler will complain.
(from comments) When testing boolean variables, you don't need to use == at all. Just use if (self.dontSendDelegate) or if (!self.dontSendDelegate).
#GeorgFritzsche is correct. When this happens I override the setter and create a breakpoint. Then take a look at the stack on the left side of your screen and trace it down to the culprit. Most likely you are changing the value somewhere else in your program.
I have a data structure that I wanted to enumerate. I tried to implement my object's NSFastEnumerator as follows:
- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state
objects:(__unsafe_unretained id [])buffer
count:(NSUInteger)len {
NSUInteger c = 0;
while (c < len) {
id obj = [self objectAtIndex:state->state];
if (obj == nil) break;
buffer[c] = obj;
c++;
state->state++;
}
state->itemsPtr = buffer;
state->mutationsPtr = nil;
return c;
}
If I use objectAtIndex directly, my object works properly. I get a nil when the index doesn't exist. But when I then use the for loop:
for (Pin *pin in coll) { ... }
the code runs through the above function fine and fills in state with what appears to be valid values and returns the number of objects, then I get an EXC_BAD_ACCESS failure at the for statement itself.
What am I doing wrong in this implementation?
I just had a similar issues, and after looking more closely into Apple's FastEnumerationSample, this part (that I had overlooked) jumped at me:
// We are not tracking mutations, so we'll set state->mutationsPtr to point into one of our extra values,
// since these values are not otherwise used by the protocol.
// If your class was mutable, you may choose to use an internal variable that is updated when the class is mutated.
// state->mutationsPtr MUST NOT be NULL.
state->mutationsPtr = &state->extra[0];
The important part being: state->mutationsPtr MUST NOT be NULL. I just used the example line provided and it worked like a charm!
I'm assuming you're using ARC. The problem may be that the buffer is an array of __unsafe_unretained objects, so ARC might be over-releasing them. But what does your objectAtIndex: method look like? This shouldn't be a problem if you are returning objects that are guaranteed to be alive at least as long as your object itself.
Instead of:
id obj = [self objectAtIndex:state->state];
use
__unsafe_unretained id = [self objectAtIndex:state->state];
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.