Why wont my singleton property autocomplete? - iphone

Anyidea why autocomplete does not work on the spaceScene property?
#import <Foundation/Foundation.h>
#import "cocos2d.h"
#class SpaceScene;
#interface SpaceSceneSingleton : NSObject
{
SpaceScene *spaceScene;
}
#property (assign) SpaceScene *spaceScene;
+(SpaceSceneSingleton*)sharedSpaceSceneSingleton;
-(void) addChildToSceneWith:(CCNode *) node andWithZindex: (int) zIndex;
-(void) runAction:(CCAction*) action;
-(void) setTouchIsEnabled:(BOOL) isEnabled;
-(void) removeChild: (CCNode *) child;
#end
#import "SpaceSceneSingleton.h"
#implementation SpaceSceneSingleton
#synthesize spaceScene;
static SpaceSceneSingleton* _sharedSpaceSceneSingleton = nil;
+(SpaceSceneSingleton*)sharedSpaceSceneSingleton;
{
#synchronized([SpaceSceneSingleton class])
{
if (!_sharedSpaceSceneSingleton)
[[self alloc] init];
return _sharedSpaceSceneSingleton;
}
return nil;
}
+(id)alloc
{
#synchronized([SpaceSceneSingleton class])
{
NSAssert(_sharedSpaceSceneSingleton == nil, #"Attempted to allocate a second instance of a singleton.");
_sharedSpaceSceneSingleton = [super alloc];
return _sharedSpaceSceneSingleton;
}
return nil;
}
-(id)init {
self = [super init];
if (self != nil) {
// initialize stuff here
}
return self;
}
-(void) addChildToSceneWith:(CCNode *) node andWithZindex: (int) zIndex
{
[self.spaceScene addChild:node z:zIndex];
}
-(void) runAction:(CCAction*) action
{
//[self.spaceScene add
}
-(void) setTouchIsEnabled:(BOOL) isEnabled
{
}
-(void) removeChild: (CCNode *) child
{
}
#end

You only declared #class SpaceScene; so within this scope nothing more is known than that a class called SpaceScene might exist. Maybe importing SpaceScene.h helps.
I would even say this should compile with warnings. Does it?

Related

Error with Categories iPhone

I've Category problem : No visible #interface for 'NSString' declares in selector 'isUrl'
NSString+NSString.h
#import <Foundation/Foundation.h>
#interface NSString (NSString)
- (BOOL)isUrl;
#end
NSString+Nsstring.m
#import "NSString+NSString.h"
#implementation NSString (NSString)
- (BOOL) isUrl {
if ([self hasPrefix:#"http://"]) {
return YES;
} else {
return NO;
}
}
#end
ViewController.m
#import "ViewController.h"
#import "NSString+NSString.h"
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
NSString* string1 = #"http://apple.com/";
NSString* string2 = #"Apple";
if ([string1 isURL]) { // **Here is an error**
NSLog (#"string1 is URL");
}
if ([string2 isURL]) { // **And here**
NSLog (#"string2 is NOT URL");
}
}
What I'm doing wrong?
isURL isn't the same as isUrl :)
You've called your method in your category isUrl but you're trying to use a method called isURL in your code.
Though you're better off letting iOS test if something is a URL or not -
-(BOOL)isURL {
return nil != [NSURL URLWithString:self];
}

how to implement Singleton Pattern in my IPhone project?

i am working on a project in wich i want to use Singleton Pattern model.
i want to any data model of my this project fallow Singleton Pattern.
i study the apple documentation regarding this
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaDesignPatterns/CocoaDesignPatterns.html#//apple_ref/doc/uid/TP40002974-CH6-SW6
and
http://www.oodesign.com/singleton-pattern.html
http://www.daveoncode.com/2011/12/19/fundamental-ios-design-patterns-sharedinstance-singleton-objective-c/
now i know my custom object classes should fallow the main rule of allocing a object but the i need the complete implementation like using of this class object
i am new in iphone app development so if i am wrong in any place in this Question please guide
Try this:
#implementation Singleton
+ (Singleton *)sharedInstance
{
static Singleton *obj = nil;
if (obj == nil)
obj = [[self alloc] init];
return obj;
}
#end
static MyClass *_sharedInstance;
+ (MyClass *)sharedMyClass
{
#synchronized([MyClass class]) {
if (_sharedInstance == nil)
[[self alloc] init];
return _sharedInstance;
}
return nil;
}
+(id) alloc
{
#synchronized([MyClass class]) {
NSAssert(_sharedInstance == nil, #"Attempted to allocate a second instance of MyClass.");
_sharedInstance = [super alloc];
return _sharedInstance;
}
return nil;
}
+ (id) allocWithZone:(NSZone *)zone
{
#synchronized([MyClass class]) {
NSAssert(_sharedInstance == nil, #"Attempted to allocate a second instance of MyClass.");
_sharedInstance= [super allocWithZone:zone];
return _sharedInstance;
}
return nil; //on subsequent allocation attempts return nil
}
- (id) copyWithZone:(NSZone *)zone
{
return self;
}
- (id)retain
{
return self;
}
- (NSUInteger)retainCount
{
return NSUIntegerMax;
}
- (oneway void)release
{
// Do nothing
}
- (id)autorelease
{
return self;
}
If you can target iOS 4 or above, I will take the following way:
//.h
+(MySingletonClass *)mySharedInstance;
-(void)doSomething;
//.m
+(MySingletonClass *)mySharedInstance {
static dispatch_once_t pred;
static MySingletonClass *shared = nil;
dispatch_once(&pred, ^{
shared = [[MySingletonClass alloc] init];
});
return shared;
}
-(void)doSomething
{
}
// override also the init if you want
To access it, do an #import MySingletonClass.h and use it wherever you want like the following:
MySingletonClass* mySharedInstance = [MySingletonClass mySharedInstance];
[mySharedInstance doSomething];
I want to any data model of my this project fallow Singleton Pattern.
Based on my experience, I would not abuse on singletons. The application could become difficult to maintain. To avoid this, put the data models within your singleton. You can access data model directly (creating properties around them) or using public methods (like for example doSomething) as wrappers.
Hope this helps.
This might be a useful reference: http://cocoasamurai.blogspot.com/2011/04/singletons-your-doing-them-wrong.html
Typically I create the object in the
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
method and have it live in that object. I make it available to the rest of the app with a macro:
#define APPLICATION ((AppDelegate*)([UIApplication sharedApplication].delegate))
as a readonly property of the app delegate
The benefit of this type of approach if you are in to mocking is that it is just another object property rather than a hidden static object.
I use:
#import <Foundation/Foundation.h>
#interface iCode_Framework : NSObject
#property (readonly, nonatomic) unsigned int iBufCapacity;
#property (readonly, nonatomic) unsigned int iPort;
#property (readonly, nonatomic) NSString * urlStr;
#end
#import "iCode_Framework.h"
static iCode_Framework * instance;
#implementation iCode_Framework
#dynamic iBufCapacity;
#dynamic iPort;
#dynamic urlStr;
- (unsigned int)iBufCapacity
{
return 1024u;
};
- (unsigned int)iPort
{
return 1978u;
};
- (NSString *)urlStr
{
return #"localhost";
};
+ (void)initialize
{
if (!instance) {
instance = [[super allocWithZone:NULL] init];
}
}
+ (id)allocWithZone:(NSZone * const)notUsed
{
return instance;
}
#end
Which is used exactly like a normal class, you call alloc and init! It is often convenient to assign to a variable to give a shorthand, because alloc and init are long to type, e.g.:
#import "iCode_FrameworkTests.h"
#import "iCode_Framework.h"
static iCode_Framework * c;
#implementation iCode_FrameworkTests
+ (void)initialize
{
c = [[iCode_Framework alloc] init];
}
- (void)setUp
{
[super setUp];
// Set-up code here.
}
- (void)tearDown
{
// Tear-down code here.
[super tearDown];
}
- (void)testSingletonNotNil
{
STAssertNotNil(c, nil);
}
- (void)testSingletonProperty
{
STAssertEqualObjects(c, [iCode_Framework alloc], nil);
}
- (void)testIBufCapacity
{
STAssertEquals(c.iBufCapacity, 1024u, nil);
}
#end
The advantage of this approach is it is used exactly like any other class and can therefore be mocked for testing.

#protocol on IOS parsing data 2 way?

I have login Code like this :
#protocol LoginDelegate
-(void)DUsername:(NSString *) username DPassword:(NSString *) password;
#end
#interface loginipad : UIViewController {
id<LoginDelegate> delegate;
IBOutlet UITextField *edusername;
IBOutlet UITextField *edpassword;
}
and then i use this object on mainViewController like this :
#interface mainViewController : UIViewController<LoginDelegate> {
and call this methode on mainViewController
-(void)DUsername:(NSString *) username DPassword:(NSString *) password{
userlogin=[username retain];
passlogin=[password retain];
if (!scm.isRunning) {
[scm connectToHost:#"localhost" onPort:8080];
}
}
This method is success to parsing data from login modalview to mainViewController, but i want show progress of process or any message from mainViewController to login modal view when login button is klick (i try MBPrgoressHUD but no success due i use this login on modal view).
My Question how i can parsing data from mainViewController to This login modalview ?
Thanks,
for call the method :
loginipad *plogin = [[loginipad alloc] initWithNibName:#"loginipad" bundle:nil];
plogin.delegate = self;
UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:plogin];
plogin.title=#"Login";
[self presentModalViewController:nc animated:YES];
[nc release];
nc = nil;
[plogin release];
plogin = nil;
answer completely edited
Your question leads to multiple solutions and strategies.
First: general posibilities to implement bidirectional data-transfer between two classes.
via multiple protocols: loose cupling but leads to import-loops which are annoying. I know ho to solve import loops for class-definitions (#class) but I dont know how to solve this for protocols
A.h:
#import "B.h"
#protocol ADelegate
-(void) adelegate:(NSString*)data;
#end
#interface A : NSObject<BDelegate>
{
id<ADelegate> delegate;
}
#end
B.h:
#import "A.h"
#protocol BDelegate
-(void) bdelegate:(NSString*)data;
#end
#interface B : NSObject<ADelegate>
{
id<BDelegate> delegate;
}
#end
via a single protocol: dense cupling :( but no import-loop (this is a working ugly style)
A.h:
//no import here needed
#protocol ADelegate
-(void) adelegate:(NSString*)data;
#end
#interface A : NSObject<BDelegate>
{
id<ADelegate> delegate;
}
#end
B.h:
#import "A.h"
#interface B : NSObject<ADelegate>
{
A* delegate;
}
#end
via pipe/stream: bidirectional data-transfer should by done using a pipe (unbuffered) or stream (buffered)
here I show you a small and simple delegate-pipe but there also exists a NSPipe/NSStream
DelegatePipe.h
#protocol DelegatePipeDelegate
- dataArrived:(NSString*)data;
#end
#interface DelegatePipe : NSObject {
NSMutableArray *delegates;
}
-(void)open:(id<DelegatePipeDelegate>)d;
-(void)close:(id<DelegatePipeDelegate>)d;
-(void)send:(NSString*)data;
#end
DelegatePipe.m
#implementation DelegatePipe
-(id)init
{
if(self = [super init])
{
delegates = [NSMutableArray array];
}
return self;
}
-(void) dealloc
{
[delegates release];
delegates = nil;
}
-(void) open:(id <DelegatePipeDelegate>)d
{
#synchronized(self)
{
if([delegates containsObject:d])
return;
//if([delegates count]>=2) //Pipe contains originally only 2 delegates. but a broadcaster is also nice ;)
// return;
[delegates addObject:d];
}
}
-(void) close:(id <DelegatePipeDelegate>)d
{
#synchronized(self)
{
[delegates removeObject:d];
}
}
-(void) send:(NSString *)data
{
#synchronized(self)
{
for(id<DelegatePipeDelegate> d in delegates)
[d dataArrived:data];
}
}
#end
Second: KVO
KVO is often used in a ModelViewController (MVC) Pattern. eg: visualize data in a view. The network-connection-state in your case is part of data and your loginipad is a view (and a controller)
Authentificator.h
typedef enum eAuthState
{
NOT_CONNECTED = 0,
LOGIN_FAILED,
CONNECING,
CONNECTED
} AuthState;
#interface Authentificator : NSObject {
AuthState state;
}
#property (nonatomic, assign) AuthState state;
#end
Authentificator.m
...
-(void) doAuthWithUsername:(NSString*)name password:(NSString*)pw
{
self.state = CONNECING;
//do network-stuff
}
//delegate from network. here NSURLConnection
-(void) connectionDidFinishLoading:(NSURLConnection *)connection
{
//parse network-answer
BOOL success = YES;
if(success)
self.state = CONNECTED;
else
self.state = LOGIN_FAILED;
}
loginipad.h
#interface loginipad : UIViewController
{
Authentificator *auth;
}
#property (nonatomic, retain) Authentificator *auth;
#end
loginipad.m
#implementation loginipad
#synthesize auth;
//override setter for more comfortable use (add/removeObserver)
-(void) setAuth:(Authentificator *)a
{
#synchronized(auth)
{
[auth removeObserver:self forKeyPath:#"state"];
[auth release];
auth = a;
[auth retain];
[auth addObserver:self forKeyPath:#"state" options:0 context:nil];
}
}
-(IBAction) buttonClicked:(id)aSender
{
self.auth = [Authentificator sharedAuthentificator];
}
-(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if(![object isKindOfClass:Authentificator.class])
return;
AuthState state = ((Authentificator*)object).state;
NSLog(#"curState: %i",state);
//do sth with state
}
- (void)dealloc {
self.auth = nil;
[super dealloc];
}

Singleton Integer Issue

I have a singleton which I hold a single integer in, my score. However when I load it form the singleton in a another view it doesn't show what I want but instead sticks at a wired 6592960. Any ideas why? Something to do with how I am using #property Im thinking, what the correct way to #property an int?
Thanks.
EDIT:
Code:
Singleton .h
#import <Foundation/Foundation.h>
#interface scoreData : NSObject {
int score;
}
#property int score;
+ (scoreData *)sharedData;
#end
Singleton .m
#import "scoreData.h"
static scoreData *sharedData = nil;
#implementation scoreData
#synthesize score;
#pragma mark -
#pragma mark Singleton Methods
+ (scoreData *)sharedData {
if(sharedData == nil){
sharedData = [[super allocWithZone:NULL] init];
}
return sharedData;
}
+ (id)allocWithZone:(NSZone *)zone {
return [[self sharedManager] retain];
}
- (id)copyWithZone:(NSZone *)zone {
return self;
}
- (id)retain {
return self;
}
- (unsigned)retainCount {
return NSUIntegerMax;
}
- (void)release {
//do nothing
}
- (id)autorelease {
return self;
}
#end
Inside my other view, I access like this and then try and change the number and of course I import the singleton:
scoreData *score = [scoreData sharedData];
score.score = 0;
MySingleton.h
#import <Foundation/Foundation.h>
#interface MySingleton : NSObject {
}
#property(nonatomic,assign) int score;
+ (MySingleton*) sharedInstance;
#end
MySingleton.m
#import "MySingleton.h"
static MySingleton *_instance;
#implementation MySingleton
#synthesize score;
+ (MySingleton*)sharedInstance
{
#synchronized(self) {
if (_instance == nil) {
_instance = [[super allocWithZone:NULL] init];
}
}
return _instance;
}
#pragma mark Singleton Methods
+ (id)allocWithZone:(NSZone *)zone
{
return [[self sharedInstance]retain];
}
- (id)copyWithZone:(NSZone *)zone
{
return self;
}
- (id)retain
{
return self;
}
- (unsigned)retainCount
{
return NSUIntegerMax;
}
- (void)release
{
}
- (id)autorelease
{
return self;
}
#end
See this xcode-template to simplify singleton-generation.
If it's a true singleton, then you can have your getter and setter simply directly access an initialized static global variable, and skip all the runtime alloc and zone busywork.
I would write the #property like this:
#property (nonatomic,assign) int score;
Also i would change sharedData:
+ (scoreData *)sharedData {
if( sharedData == nil ){
sharedData = [[self alloc] init];
}
return sharedData;
}
Edit: I tried your code and got EXC_BADACCESS because it went recursive here:
+ (id)allocWithZone:(NSZone *)zone {
return [[self sharedManager] retain];
}
When i removed that method everything worked as expected.

How do I make a custom delegate protocol for a UIView subclass?

I'm making some tabs and I want to have my own delegate for them but when I try to send an action to the delegate nothing happens.
I also tried following this tutorial:
link text
But it doesn't work for me :(
Here is my code:
TiMTabBar.h
#protocol TiMTabBarDelegate;
#interface TiMTabBar : UIView {
id<TiMTabBarDelegate> __delegate;
...
int selectedItem;
...
}
//- (id)init;
- (id)initWithDelegate:(id)aDelegate;
- (void)setSelectedIndex:(int)item;
..
#property (nonatomic) int selectedItem;
#property(assign) id <TiMTabBarDelegate> __delegate;
..
...
#end
#protocol TiMTabBarDelegate<NSObject>
//#optional
- (void)tabBar:(TiMTabBar *)_tabBar didSelectIndex:(int)index;
#end
TiMTabBar.m:
#import "TiMTabBar.h"
...
#interface NSObject (TiMTabBarDelegate)
- (void)tabBar:(TiMTabBar *)_tabBar didSelectIndex:(int)index;
#end
#implementation TiMTabBar
#synthesize selectedItem;
#synthesize __delegate;
...
/*
- (id)init
{
...
return self;
}
*/
- (id)initWithDelegate:(id)aDelegate;
{
//[super init];
__delegate = aDelegate;
return self;
}
- (void)awakeFromNib
{
//[self init];
//[self initWithDelegate:self];
...
}
- (void)setSelectedIndex:(int)item {
selectedItem = item;
if (self.__delegate != NULL && [self.__delegate respondsToSelector:#selector(tabBar:didSelectIndex:)]) {
[__delegate tabBar:self didSelectIndex:selectedItem];
}
...
if (item == 0) {
...
} else if (item == 1) {
...
} else if (item == 2) {
...
} else if (item == 3) {
...
} else if (item == 4) {
...
} else {
...
}
}
/*
- (void)tabBar:(TiMTabBar *)_tabBar didSelectIndex:(int)index;
{
//[delegate tabBar:self didSelectIndex:index];
//if (self.delegate != NULL && [self.delegate respondsToSelector:#selector(tabBar:didSelectIndex:)]) {
//[delegate tabBar:self didSelectIndex:selectedItem];
//}
NSLog(#"tabBarDelegate: %d",index);
}
*/
#end
The delegate only works works inside itself and not in any other files like:
#interface XXXController : UIViewController <TiMTabBarDelegate> {
...
...
IBOutlet TiMTabBar *tabBar;
...
}
...
#end
XXXController.m:
#import "XXXController.h"
#import <QuartzCore/QuartzCore.h>
#implementation XXXController
- (void)viewDidLoad {
[super viewDidLoad];
[self becomeFirstResponder];
...
tabBar = [[TiMTabBar alloc] initWithDelegate:self];
//tabBar.__delegate = self;
...
}
#pragma mark TiMTabBar Stuff
- (void)tabBar:(TiMTabBar *)_tabBar didSelectIndex:(int)index;
{
NSLog(#"Controller/tabBarDelegate: %d",index);
}
#end
None of this seems to work in XXXController. Anyone know how to make this work?
In your XXXController viewDidLoad after you alloc and init a new TiMTabBar are you adding it to the controller's view? If not, perhaps the tab bar in your view that you are clicking on is one loaded from the nib that does not have the delegate set.
It looks like - In awakeFromNib, you are setting the delegate to itself. So whenever you try to send the delegate messages, you are actually sending them to your instance of TiMTabBar, not XXXController.