Compiler error - iOS "expected ")" before "Question - ios

What's wrong with the following code? Xcode 4 is saying that the two method declarations with "Question" don't compile due to an '"expected ")" before "Question"; message, as indicated in the comments in the code below. The Question class compiles and this code has been working previously. I made some changes to Questions, but backed them out to try to figure out this compile time error.
#import <Foundation/Foundation.h>
#import "Question.h"
#interface AppState : NSObject {
int chosenAnswer;
int correctAnswers;
int currentQuestionNumber;
// this will contain the hash table of question objects
NSMutableDictionary *questionHash;
}
#property (nonatomic) int chosenAnswer;
#property (nonatomic) int correctAnswers;
#property (nonatomic) int currentQuestionNumber;
#property (nonatomic, retain) NSDictionary *questionHash;
- (void) printQuestions;
- (void) printDescription;
- (void) addQuestion: (Question *) question; // <==== error
- (int) numberOfQuestions;
- (void) saveState;
- (void) resetState;
- (Question *) currentQuestion; // <===== error
#end
Here's Question.h:
#import <Foundation/Foundation.h>
#import "AppState.h"
#interface Question : NSObject {
NSString *questionTxt;
int correctAnswer;
int number;
// this will contain the hash table of questions_answer objects
NSMutableDictionary *answerHash;
}
#property (nonatomic, retain) NSString * questionTxt;
#property (nonatomic) int correctAnswer;
#property (nonatomic) int number;
#property (nonatomic, retain) NSMutableDictionary *answerHash;
-(void) addAnswer: (NSString *) answer;
- (NSMutableArray *) answerArray;
- (void) printDescription;
- (void) printAnswers;
- (NSString *) correctAnswerText;
- (Question *) currentQuestion;
#end

Circular dependency? AppState is importing Question and Question is importing AppState.
Forward-declare one of them to break the cycle, e.g. use #class Question before your AppState #interface statement, like this
#class Question;
#interface AppState : NSObject {
int chosenAnswer;
int correctAnswers;
int currentQuestionNumber;
// this will contain the hash table of question objects
NSMutableDictionary *questionHash;
}
...
Related question: #class vs. #import

When you #import "AppState.h" in Question you make a cyclic dependency.
It would be best to move #import "AppState.h" and #import "Question.h" to implementation part. In the header just leave
#class Question;
and
#class AppState;
before interface declaration.

Related

Objective-C accessing singleton's property causing EXC_BAD_ACCESS crash

I've got a singleton class KTTTeacherService that has a single property currentTeacher. This property is nil initially and is updated with the static method KTTTeacherService#updateCurrentTeacher. After currentTeacher is updated, when I try to access it, my app crashes with a EXC_BAD_ACCESS error.
KTTTeacherService.h
#import <Foundation/Foundation.h>
#import "KTTeacher.h"
#interface KTTTeacherService : NSObject
#property (nonatomic, assign) KTTeacher* currentTeacher;
+ (KTTTeacherService*)shared;
+ (KTTeacher*)currentTeacher;
+ (NSString*)apiKey;
+ (void)updateCurrentTeacher:(KTTeacher*) teacher;
- (KTTeacher*)retrieveCurrentTeacher;
#end
KTTTeacherService.m
#import "KTTTeacherService.h"
#import "KTTeacher.h"
static KTTTeacherService* _singleton = nil;
#implementation KTTTeacherService;
+ (KTTTeacherService*) shared {
if(_singleton == nil) {
_singleton = [[KTTTeacherService alloc] init];
}
return _singleton;
}
+ (KTTeacher*) currentTeacher {
KTTTeacherService* shared = [KTTTeacherService shared];
if(shared == nil) {
return nil;
}
return [shared retrieveCurrentTeacher];
}
+ (NSString*) apiKey {
KTTeacher* teacher = [KTTTeacherService currentTeacher];
return teacher == nil ? nil : teacher.apiKey;
}
+ (void) updateCurrentTeacher:(KTTeacher*) teacher {
[KTTTeacherService shared].currentTeacher = teacher;
}
- (KTTeacher*) retrieveCurrentTeacher {
return _currentTeacher;
}
#end
KTTeacher.h
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#class KTClass, KTGroup, KTTeacherNote;
#interface KTTeacher : NSManagedObject
#property (nonatomic, strong) NSString * apiKey;
#property (nonatomic, strong) NSNumber * serverIdentifier;
#property (nonatomic, strong) NSString * firstName;
#property (nonatomic, strong) NSString * lastName;
#property (nonatomic, strong) NSString * photoPathOnServer;
#property (nonatomic, strong) NSString * username;
#property (nonatomic, strong) NSString * hashedPassword;
#property (nonatomic, strong) NSString * salt;
#property (nonatomic, strong) NSSet *classes;
#property (nonatomic, strong) NSSet *groups;
#property (nonatomic, strong) NSSet *notes;
#end
#interface KTTeacher (CoreDataGeneratedAccessors)
- (void)addClassesObject:(KTClass *)value;
- (void)removeClassesObject:(KTClass *)value;
- (void)addClasses:(NSSet *)values;
- (void)removeClasses:(NSSet *)values;
- (void)addNotesObject:(KTTeacherNote *)value;
- (void)removeNotesObject:(KTTeacherNote *)value;
- (void)addNotes:(NSSet *)values;
- (void)removeNotes:(NSSet *)values;
- (void)addGroupsObject:(KTGroup *)value;
- (void)removeGroupsObject:(KTGroup *)value;
- (void)addGroups:(NSSet *)values;
- (void)removeGroups:(NSSet *)values;
#end
KTTeacher.m
#import "KTTeacher.h"
#import "KTClass.h"
#import "KTTeacherNote.h"
#implementation KTTeacher
#dynamic apiKey;
#dynamic serverIdentifier;
#dynamic firstName;
#dynamic lastName;
#dynamic photoPathOnServer;
#dynamic username;
#dynamic hashedPassword;
#dynamic salt;
#dynamic classes;
#dynamic groups;
#dynamic notes;
#end
Where the crash happens:
KTTTeacherService* teacherService = [KTTTeacherService shared];
KTTeacher* currentTeacher = teacherService.currentTeacher;
Specifically here: teacherService.currentTeacher
Why is this happening? After doing some googling, I found some info about this error being caused by accessing references that have been garbage collected, but I don't understand why this variable would be garbage collected because the singleton keeps a reference.
Property written incorrectly. Use strong, weak, retain instead assign
property (nonatomic, assign) KTTeacher* currentTeacher;
I tried to reproduce the error and I could not. Create a project and put the classes KTTTeacherService, KTTeacher (empty class with the apiKey property) Everything works fine. Therefore you must have the error in the KTTeacher class.
In the viewDidLoad I have the following:
KTTTeacherService* teacherService = [KTTTeacherService shared];
// updateCurrentTeacher, for default is nil
KTTeacher *teacher = [[KTTeacher alloc] init];
[KTTTeacherService updateCurrentTeacher:teacher];
KTTeacher* currentTeacher = teacherService.currentTeacher
When you call currentTeacher method then, _currentTeacher (property) has a value now.

Property Inheritance in Objective C

I want to inherit my base class properties and methods which will be used by my several derived classes. I want these properties and methods to be exactly protected so that they will only be visible in derived class and not to any external class. But it always gives me some errors.
#interface BasePerson : NSObject
#end
#interface BasePerson ()
#property (nonatomic, strong) NSMutableArray<Person*>* savedPersons;
#property (nonatomic) BOOL shouldSavePerson;
#end
#interface DerivedPerson1 : BasePerson
#end
#implementation DerivedPerson1
- (instancetype)init
{
if (self = [super init]) {
self.savedPersons = [NSMutableArray array];
self.shouldSavePerson = NO;
}
return self;
}
It always gives me an error that
Property 'savedPersons' not found on object of type 'DerivedPerson1 *'
Property 'shouldSavePerson' not found on object of type 'DerivedPerson1 *'
How i can make use of inheritance in Objective C, I don't want savedPersons and shouldSavePerson properties to be visible to external classes. I only want them to visible in my base class and all the derived classes.
Any help will be great. Thanks
This is not something that the objectiveC really support. There are some ways though. So lets see.
If you put a property in the source file class extension then it is not exposed and you can not access it in the subclass either.
One way is to put all of the subclasses into the same source file as the base class. This is not a good solution at all as you do want to have separate files for separate classes.
It seems logical to import the BaseClass.m in the SubClass source file but that will produce a linker error saying that you have duplicate symbols.
And the solution:
Separate the extension into a separate header. So you have a MyClass
Header:
#import <Foundation/Foundation.h>
#interface MyClass : NSObject
#end
Source:
#import "MyClass.h"
#import "MyClassProtected.h"
#implementation MyClass
- (void)foo {
self.someProperty = #"Some text from base class";
}
#end
Then you create another header file (only the header) MyClassProtected.h which has the following:
#import "MyClass.h"
#interface MyClass ()
#property (nonatomic, strong) NSString *someProperty;
#end
And the subclass MyClassSubclass
Header:
#import "MyClass.h"
#interface MyClassSubclass : MyClass
#end
And the source:
#import "MyClassSubclass.h"
#import "MyClassProtected.h"
#implementation MyClassSubclass
- (void)foo {
self.someProperty = #"We can set it here as well";
}
#end
So now if the user MyClassSubclass he will not have the access to the protected property which is essentially what you want. But the downside is the user may still import MyClassProtected.h after which he will have the access to the property.
Objective-C doesn't have member access control for methods, but you can emulate it using header files.
BasePerson.h
#interface BasePerson : NSObject
#property (strong,nonatomic) SomeClass *somePublicProperty;
-(void) somePublicMethod;
#end
BasePerson-Private.h
#import "BasePerson.h"
#interface BasePerson ()
#property (nonatomic, strong) NSMutableArray<Person*>* savedPersons;
#property (nonatomic) BOOL shouldSavePerson;
#end
BasePerson.m
#import "BasePerson-Private.h"
...
DerivedPerson1.h
#import "BasePerson-Private.h"
#inteface DerivedPerson1 : BasePerson
...
#end
Now any class that #imports BasePerson.h will only see the public methods. As I said though, this is only emulating access control since if a class #imports *BasePerson-Private.h" they will see the private members; this is just how C/Objective-C is.
We can achieve using #protected access specifier
#interface BasePerson : NSObject {
#protected NSMutableArray *savedPersons;
#protected BOOL shouldSavePerson;
}
DerivedPerson1.m
#implementation DerivedPerson1
- (instancetype)init
{
if (self = [super init]) {
self->savedPersons = [NSMutableArray array];
self->shouldSavePerson = NO;
}
return self;
}
#end
OtherClass.m
#import "OtherClass.h"
#import "BasePerson.h"
#implementation OtherClass
- (void)awakeFromNib {
BasePerson *base = [[BasePerson alloc]init];
base->savedPersons = #[];//Getting Error. Because it is not a subclass.
}
#end

Objective-C Class extensions

I've started learning obj-C just recently so sorry if I'm missing something obvious.
I want to access "passCode" (extension) with clpPlayerStats object, but it's impossible to do ("Property not found on object..."). Is there any simple way to fix this?
clpPlayerStats.h
#import <Foundation/Foundation.h>
#interface clpPlayerStats : NSObject
#property(nonatomic, copy) NSString* name;
#end
clpPlayerStats.m
#import "clpPlayerStats.h"
#interface clpPlayerStats()
#property (nonatomic) unsigned int passCode;
#end
#implementation clpPlayerStats
#end
main.m
#import <Foundation/Foundation.h>
#import "clpPlayerStats.h"
int main(int argc, const char * argv[]) {
#autoreleasepool {
clpPlayerStats *clapslock = [[clpPlayerStats alloc] init];
NSString *username = [NSString stringWithFormat:#"xxxPussySlayerxxx"];
clapslock.name = username;
clapslock.passCode = 12; // <------ "Property not found on object..."
}
return 0;
}
First, class names should always start with second letters.
Secondly, Class Extensions extend the #interface of the class. And, with all things C, whether or not a declaration of anything can be seen is entirely dependent on whether the compiler can see the declaration at the time of use.
So, if you want to declare something that is semi-private, then you would typically move your #interface ClpPlayerStats() extension to a Private header file; ClpPlayerStats_Private.h. Then, if you want to access the "private" API, you #import ClpPlayerStats_Private.h.
There really isn't a formal notion of privacy in Objective-C. Just visibility to the compiler.
With this code:
#interface clpPlayerStats()
#property (nonatomic) unsigned int passCode;
#end
you are declaring a private property. If you want to use passCode outside the scope of your class you have to add in the public interface:
#import <Foundation/Foundation.h>
#interface clpPlayerStats : NSObject
#property(nonatomic, copy) NSString* name;
#property (nonatomic) unsigned int passCode;
#end
and remove the interface in the .m

Parse Issue in Xcode 4.6.3 - "Expected a type" - Can't find the error

I have a Problem with Xcode:
At the moment I am working on an application for iOS SDK 6.1. Somedays ago I was implementing some methods and tried to compile the project.
Then something strange happened:
Compilation failed and I got some errors (see picture below) in two files, which aren't related to the methods I worked on.
I searched for errors in my code but couldn't find any.
Then I closed the project and opened it again: They were still here.
Then I closed the project and Xcode and reopened both: They were still here.
Then I created a new project and copied all the code: The issue appeared again.
Now I am stuck and have no clue what to do. Do I miss something in my code?
Please help me!
---
EDIT 1:
Here are some code snippets, which should show my code after I followed the suggestions of Martin R:
// PlayingCardDeck.h
#class PlayingCard;
#interface PlayingCardDeck : NSObject
- (void) addCard: (PlayingCard *) card atTop: (BOOL) atTop;
- (PlayingCard *) drawRandomCard;
- (BOOL) containsCard: (PlayingCard *) card;
- (BOOL) isCardUsed: (PlayingCard *) card;
- (void) drawSpecificCard: (PlayingCard *) card;
- (void) reset;
#end
// PlayingCardDeck.m
#import "PlayingCardDeck.h"
#interface PlayingCardDeck()
// PlayingCard.h
#import <Foundation/Foundation.h>
#import "RobinsConstants.h"
#import "PlayingCardDeck.h"
//#class PlayingCardDeck;
#interface PlayingCard : NSObject
+ (NSArray*) suitStrings;
+ (NSArray*) rankStrings;
+ (NSUInteger) maxRank;
- (id)initCardWithRank: (NSUInteger) r andSuit: (NSString*) s;
- (NSString*) description;
- (NSUInteger) pokerEvalRankWithDeck: (PlayingCardDeck *) deck;
- (NSAttributedString *) attributedContents;
- (BOOL) isEqual:(PlayingCard*)object;
#property (strong, nonatomic) NSString *contents;
#property (nonatomic, getter = isUsed) BOOL used;
#property (nonatomic, readonly) NSInteger rank;
#property (nonatomic, readonly, strong) NSString * suit;
#end
// PlayingCard.m
#import "PlayingCard.h"
#interface PlayingCard()
That looks like a typical "import cycle":
// In PlayingCardDeck.h:
#import "PlayingCard.h"
// In PlayingCard.h:
#import "PlayingCardDeck.h"
Replacing one of the #import statements by #class should solve the problem, e.g.
// In PlayingCardDeck.h:
#class PlayingCard; // instead of #import "PlayingCard.h"
And in the implementation file you have to import the full interface:
// In PlayingCardDeck.m:
#import "PlayingCardDeck.h"
#import "PlayingCard.h" // <-- add this one
There is something wrong in PlayingCard.h. This error causes the compiler to not know what a "PlayingCard *" is.
Can you show the code from PlayingCard.h?
Make sure the PlayingCard.m is added to your applications target! I would think it isn't (click the .m file and check your apps target in the inspector window on the right side pane)

no known class method for selector confusion

I know this is a newbie question, but I am all confused. How should I call class method from another class, or shouldn't I?
Here is my ClassA and CoreDataHelper:
#import <Foundation/Foundation.h>
#interface ClassA : NSObject {
}
#property (nonatomic, retain) NSString * sessionId;
#property (nonatomic, retain) NSString * token;
#property (nonatomic, retain) NSString * userid;
+ (void) pullOfflineDataWithContext:(NSManagedObjectContext *)managedObjectContext ;
#end
#import "ClassA.h"
#import "CoreDataHelper.h"
#implementation ClassA
+ (void) pullOfflineDataWithContext:(NSManagedObjectContext *)managedObjectContext {
// get Contacts, Accounts, Meetings into Core Data
bool asd =[CoreDataHelper insertAllObjectsForEntity:#"Contact" andContext:managedObjectContext initCoreData:jsonDict];
}
#end
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#interface CoreDataHelper : NSObject
//For inserting objects
+(BOOL)insertAllObjectsForEntity:(NSString*)entityName andContext:(NSManagedObjectContext *)managedObjectContext;
#end
You are calling a class method from another in the right way except the method signature is not the same as it is declared;
bool asd =[CoreDataHelper insertAllObjectsForEntity:#"Contact"
andContext:managedObjectContext
initCoreData:jsonDict];
The declaration of +insertAllObjectsForEntity:andContext: does not have the last one in the calling code above
+(BOOL)insertAllObjectsForEntity:(NSString*)entityName
andContext:(NSManagedObjectContext *)managedObjectContext;
Like:
[ClassName method];
Instead of:
[instance method];
In your example would be then:
[ClassA pullOfflineDataWithContext];

Resources