How do you import a category defined within it's parent class in objective-c? - objective-c-category

I have a category following the format below, designed to encapsulate simplistic methods only necessary because they will be changed by children classes. How do I import this category into other classes, such as ClassOneTests.m, ClassOneA.h, .m and ClassOneB.h, .m?
#import "ClassOne+MyCategory.h" gives an error.
ClassOne.m
#import "ClassOne.h"
#interface ClassOne ()
-(void)MethodOne
#end
#interface ClassOne (MyCategory)
-(NSString *)servantToMethodOne
#end
#implementation ClassOne
-(void)MethodOne {
[self servantToMethodOne];
...
}
#end
#implementation ClassOne (MyCategory)
...
#end

The solution is to separate the category interface into ClassOne.h and leave the imports as they are.

Related

Unrecognized Selector Sent To Class Error

So i have a class called IAP with a .h and .m file. the .h looks like this:
#import <UIKit/UIKit.h>
#import <StoreKit/StoreKit.h>
#interface IAP : UIViewController <SKProductsRequestDelegate, SKPaymentTransactionObserver, UIAlertViewDelegate>
+(void)myIAPWithItem;
#end
But when I call the function myIAPWithItem I get and error. I call it like this:
[IAP myIAPWithItem];
Also there is an item paramater I just took it off to test.
Do you have an implementation in your .m file?
// in IAP.m
#implementation IAP
+(void)myIAPWithItem {
// do something
}
#end

Xcode 4.6 "No visable #interface for 'PlayingCardDeck' declares the selector 'addCard:AtTop:'

I know this is a common problem, however I couldn't find the solution to mine.
I'm following cs193p Standford course, following letter by letter the code at the lecture slides, and Xcode 4.6 still produces an error witch didn't occur to Xcode 4.4.something...
PlayingCardDeck.h:
#import "Deck.h"
#interface PlayingCardDeck : NSObject
#end
PlayingCardDeck.m:
#import "PlayingCardDeck.h"
#import "PlayingCard.h"
#implementation PlayingCardDeck
...
[self addCard:card atTop:YES]; //problem occurs here
...
#end
deck.h:
#import <Foundation/Foundation.h>
#import "Card.h"
#interface Deck : NSObject
- (void)addCard:(Card *)card atTop:(BOOL)atTop;
...
#end
deck.m:
#import "Deck.h"
#interface Deck()
#property (strong, nonatomic) NSMutableArray *cards;
#end
#implementation Deck
...
- (void)addCard:(Card *)card atTop:(BOOL)atTop
{
if (atTop)
[self.cards insertObject:card atIndex:0];
else
[self.cards addObject:card];
}
...
#end
By logic, addCard:atTop: should be a (+) method? In the lecture it was being a (-) just fine. In addition, after trying to change it to a (+) method, it creates 6 additional problems witch demand using entirely different syntax for each time I'm going for "self".
In short, I'm really confused by now...
Problem is addCard: atTop is a method of Deck, not a method ofPlayingCardDeck.
Maybe PlayingCardDeck should inherit from Deck? Or there is an iVar of PlayingCardDeck which is a deck?

Expected Identifier or "(" before "{" token

Somehow I got this error in XCode 4.0.2, not sure what is wrong.
File: HomeViewController.h
#import <UIKit/UIKit.h>
#interface HomeViewController : UIViewController <UITabBarDelegate>
{
UIButton *Button1, *Button2, *Button3;
}
#property (nonatomic, retain) IBOutlet UIButton *Button1;
#property (nonatomic, retain) IBOutlet UIButton *Button2;
#property (nonatomic, retain) IBOutlet UIButton *Button3;
.... other member functions...
....
#end
File: HomeViewController.m
......
#import "RemoteServiceManager.h"
#interface HomeViewController()
{ //This is where the error happens: Expected Identifier or "(" before "{" token
RemoteServiceManager* serviceManager;
}
#end
#implementation HomeViewController
#synthesize Button1, Button2, Button3;
.... other member functions
....
#end
Looks like it does not recognize RemoteServiceManager. Wherever I used the serviceManager, it will say HomeViewController has no member named serviceManager.
Is it possible that is caused by XCode version? I am using XCode 4.0.2 on Mac OS X 10.6.7.
Thanks.
you cant add instance variables to private categories.
put properties in there instead, and synthesize them to obtain a variable as well as an internal getter/setter
#interface HomeViewController
#property (nonatomic, strong) NSString *privateProperty;
#end
#implementation HomeViewController
#synthesize privateProperty = _privateProperty;
#end
or you can add the instance variable to the class itself.
#implementation HomeViewController
NSString *privateVariable;
#end
Bear in mind also. that if you create a category in another file, any variables you declare in the body of that category will be static across all instances. definitely something to keep an eye out for.
To recap. you can create a variable in the interface of the main category. or in the implementation of the main category.
and the private category is for you to add prototypes to your class that will let the rest of the file know they "will be/are" available.
the old xcode cant do this, no. it does know class extensions yet because it ships with an older version of the LLVM compiler
You probably found your answer, but I post the answer here for somebody who encounters the same problem:
as Daij said, the problem is due to the version of compiler, so to fix this you need to change the compiler setting:
Build Setting > Build Options > Compiler for C/C++/ObjectiveC
Change value from "LLVM GCC 4.2" to "Apple LLVM compiler 4.2"
Hope it helps.

#import breaks build in Xcode with forward class reference

I subclasssed one of my view controllers and try to #import the header file of the new class in one of the other header files.
As soon as I include that #import, the entire build goes crazy, with errors in many classes, such as these:
Cannot find protocol declaration...
Cannot find interface declaration...
Unknown type name...
Incompatible pointer types...
These errors are all in files that are not directly related to the new class, it's superclass, or to the file with the import.
As soon as I remove the #import, the build is fine.
Here is the subclass definition, in the files ReadOnlySearchVC.h and ReadOnlySearchVC.m. As can be seen, this is just the template created by Xcode when I initially created the new class.
Header file of the subclass:
#import "AdvancedSearchFormVC.h"
#interface ReadOnlySearchVC : AdvancedSearchFormVC
#end
and Code file of the subclass:
#import "ReadOnlySearchVC.h"
#interface ReadOnlySearchVC ()
#end
#implementation ReadOnlySearchVC
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
Here is the header file, where I import the subclass ReadOnlySearchVC in the class ResultsHeaderView
Header file of a referencing class:
#import <UIKit/UIKit.h>
#import "ReadOnlySearchVC.h" // this is the offending line
#class SearchTerms;
#class DataInterfaceObject;
#class MapController;
#protocol resultsHeaderDelegate
- (void) collapseSection:(NSInteger) section;
- (void) expandSection:(NSInteger) section;
#optional
- (void) deleteSection:(NSInteger) section;
- (void) headerDeleteButtonWillShow;
- (void) headerDeleteButtonDidHide;
#end
#interface ResultsHeaderView : UIView <UIGestureRecognizerDelegate>{
... the rest of the file ...
The second line, #import "ReadOnlySearchVC.h" is creating the problem.
I updated Xcode from 4.3.1 to 4.3.3 and it didn't change. I did a clean build, and it didn't change.
I can only imagine there is some kind of circular reference, but I'm not sure how to deal with it.
Now this is a little strange, because I did have it working initially, with just some skeleton code, but including what is shown above. At some point as I added the rest of the design to the two classes shown above, it broke, and I'm not sure why. Stripping it back to these basics still demonstrates the problem.
Does anyone have an idea what I am looking at?

Can't load an NSMutableArray with UIView objects

On my game board (which is called GameViewController), I have six Seats (in the xib) which are nothing more than subclassed UIViews (so I also have Seat.h and .m files in my project). When the game board gets initialized these seats also get created (thanks to the xib). I want to have the seats loaded into an NSMutableArray so that I can use them later. For some reason I can't get it to work.
In my GameViewController header file I've added NSMutableArray *seats; as an instance variable and included #class Seat; above the interface declaration.
In my awakeFromNib method of the GameViewController I have seats = [[NSMutableArray arrayWithCapacity:6] retain]; So the array should be initialized when the game board appears.
Then in my Seat header file I've included GameViewController *controller; as an instance variable and included #class GameViewController above the interface declaration. I've also added and synthesized a property for the GameViewController.
In the Seat's awakeFromNib method I have [controller registerSeat:self];
This calls a method in my GameViewController that has only one line: [seats addObject:seat]; This should add the seat to the array. But for some reason this method never seems to get called. Or if it does, I can never tell. When I debug, focus never goes to the registerSeat method even though the seats do get added to the board. I hope this all makes sense. If the code is needed, I can provide it. It might be easier to do that anyway. What do you guys think? I'm stumped at the moment.
The method declaration is as follows:
- (void) registerSeat:(Seat *)seat;
GameViewController.h:
#import <UIKit/UIKit.h>
#class Seat;
#interface GameViewController : UIViewController {
NSMutableArray *seats;
}
- (void) registerSeat:(Seat *)seat;
#end
GameViewController.m
#import "GameViewController.h"
#import "Seat.h"
#implementation GameViewController
- (void)awakeFromNib {
seats = [[NSMutableArray arrayWithCapacity:6] retain];
}
- (void) registerSeat:(Seat *)seat {
[seats addObject:seat];
NSLog(#"seat has been registered");
}
#end
Seat.h:
#import <UIKit/UIKit.h>
#class GameViewController;
#interface Seat : UIView {
GameViewController *controller;
}
#property (nonatomic, retain) IBOutlet GameViewController *controller;
#end
Seat.m:
#import "Seat.h"
#import "GameViewController.h"
#implementation Seat
#synthesize controller;
- (void) awakeFromNib {
[controller registerSeat:self];
}
#end
What you're doing here is what Xcode 4's IBOutletCollection is designed to solve. In your NIB, select all of your Seat views (these should be called SeatView, BTW. Seat should be a model class, not a view class). Drag the selected group to your GameViewController header and request an IBOutletCollection. This will wire them all as a random-ordered array. (Why they chose to make it a random-ordered array is beyond me; it's a somewhat insane construct, but it exactly matches what you're trying to do above.)
As #highlycaffeinated notes, the most likely reason for your current code failing is that you've failed to wire your controller and it's nil. When "nothing happens" in Objective-C, it's almost always because you're talking to nil.

Resources