I have been trying to figure this out for DAYS. I am a beginner, so please bear with me. I have read a bunch of articles on delegation but I still just don't get it. Any help would be much appreciated.
Header
#protocol MidiInit <NSObject>
#end
#interface CBAppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) id midiDelegate;
-(id) initWithDelegate :(id <MidiInit>) delegate;
#end
Implementation
#synthesize midiDelegate;
-(id) initWithDelegate:(id<MidiInit>)delegate
{
if ((self = [super init]))
{
self.midiDelegate = delegate;
midi = [[MidiClass alloc] initWithDelegate://not sure what to put here];
}
return self;
}
It would help to know what you are trying to achieve, but from what you're showing us, pretty much everything looks wrong :-)
Are you showing us the application delegate? If so, what is the point of delegating to another delegate from the application delegate? It doesn't look like a standard approach.
Second, you probably don't want a 'strong' reference to a delegate, could lead to memory leaks.
But honestly, I don't think the real problem here is what you're pointing too, the entire approach seems to be wrong. Tell us more about what you're trying to achieve and I'll try to update my answer accordingly.
Related
I'm fairly new to objective-c and have just encountered an error i've not seen before.
I'm trying to set a Text Field cell as 'selectable', but i get the error "No Setter method 'setIsSelectable' for assignment to property."
Here are the .h and .m files.
Thanks.
DataPanel.h
#import <Cocoa/Cocoa.h>
#interface DataPanel : NSPanel
#property (weak) IBOutlet NSTextFieldCell *textField;
#end
DataPanel.m
#import "DataPanel.h"
#implementation DataPanel
#synthesize textField = _textField;
- (void) awakeFromNib{
_textField.stringValue = #"1.1 Performance standards The overall objective of the performance standards in Section 1.1 is to provide acoustic conditions in schools that (a) facilitate clear communication of speech between teacher and student, and between students, and (b) do not interfere with study activities.";
_textField.isSelectable = YES;
}
#end
In Objective-C, BOOL properties which start with 'is' are usually the getter of the property only, and not the property itself.
Its a convention.
Just for general knowledge, you can do so yourself by declaring properties in the following manner:
#property (nonatomic, getter=isAvaiable) BOOL available;
So trying to set the above, while using isAvailable will not work, since it is the getter method, and you can't set a getter.
As for your question,
Try changing your code from _textField.isSelectable = YES; to either of the below, and it should work.
_textField.selectable = YES;
[_textField setSelectable:YES];
Good luck mate.
I created an NSTextField in my code:
.h :
#interface AppDelegate : NSObject <NSApplicationDelegate>
{
IBOutlet NSTextField *numberOfConnectionsTextField;
}
#property (nonatomic, retain) NSTextField *numberOfConnectionsTextField;
.m :
#synthesize numberOfConnectionsTextField;
I change the value of the field here:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
[numberOfConnectionsTextField setStringValue:#"0"];
}
And the value successfully changes. However, when I try to the change the value here:
- (void)connectionNumber:(NSString *)number {
[numberOfConnectionsTextField setStringValue:number];
NSRunAlertPanel(#"", number, #"", #"", #"");
}
The NSTextField didn't change. BUT, the NSRunAlertPanel did trigger with the 'number' string correctly.
Any ideas? I can't seem to find what I did wrong...
Your code looks quite good. There is no error, the first reason is always of not connecting the outlet to the object but as you are able to change in applicationDidFinishLaunching:, so that is not the issue here.
But You did not mentioned about "-(void)connectionNumber:(NSString *)" is this in the same class? or you have created same iboutlet in another class and missed something?
Or you manually released the outlet numberOfConnectionsTextField ? Please check if it is not null? like
if(numberOfConnectionsTextField){
NSLog(#"Still exist")
}
Another reason might be, from which method are you calling "-(void)connectionNumber:(NSString *)", many a times it is seen that people call set/get of outlet from init.
Please comment if you are doing every thing correct...
It's probably safer to use self.numberOfConnectionsTextField then the variable name numberOfConnectionsTextField alone. This kind of error happened to me when I first learn objective c. Some of the IBOutLet gone nil after a period of time.
Try to use self.variablename for strong , synthesize variable
Disclaimer:
I've been learning Objective C/Cocoa for 2 months or so, and I promised myself that I would always try and find the answer myself rather than clogging the internet with dumb noob questions. At this point I'm just confused all over and I think I would benefit at this point from asking questions. I apologize in advance.
Problem:
I'm trying to write a master-detail style app (this is just for practice) called "My Dream Garage". Basically I want to store car objects and their properties. I have a "Car" class that looks like this:
#import <Foundation/Foundation.h>
#interface Car : NSObject
#property (nonatomic, strong) NSString *brand, *model, *trimLevel;
#property (nonatomic, strong) NSNumber *modelYear, *engineSizeinL, *weight;
#property (nonatomic, strong) id image;
#end
In my main .XIB file I have an NSTableView and a bunch of text labels that will display each property (and an imagewell for the image).
My question is how do I store this data? I understand what NSArray, NSDictionary, ArrayController and DictionaryController are individually. I'm just a little confused on how to make them work together. When I add a new "car", am I supposed to instantiate a new "Car" object with it's properties? At that point do I add the new object to an array and then release the created "Car" object? Do I link the tableview and text-labels to an NSDictionary Controller? I'm not even sure what I should be asking at this point.
Perhaps I'm in a bit over my head. What other than Apple's documentation (which is very good but too verbose for an amateur) would be recommended to learn how to create apps similar to this?
Any help is greatly appreciated. Thank you.
Lots of questions here:
Are you wanting to store them somewhat permanently? If so, you need to start learning Core Data.
What does the implementation file look like for the Car class? How are you (or are you) instantiating and initializing a new object?
My class objects usually look something like this:
Interface:
#interface UserInfo : NSObject {
NSString *_networkID;
NSString *_displayName;
NSString *_userDomain;
BOOL _loggedIn;
}
#property(nonatomic,strong) NSString *networkID;
#property(nonatomic,strong) NSString *displayName;
#property(nonatomic,strong) NSString *userDomain;
#property(nonatomic) BOOL loggedIn;
-(id) initWithUserNetworkID:(NSString *)networkID
displayName:(NSString *)displayName
userDomain:(NSString *)userDomain;
#end
Implementation:
#import "UserInfo.h"
#implementation UserInfo
#synthesize networkID = _networkID;
#synthesize displayName = _displayName;
#synthesize loggedIn = _loggedIn;
#synthesize userDomain = _userDomain;
-(id) initWithUserNetworkID:(NSString *)networkID
displayName:(NSString *)displayName
userDomain:(NSString *)userDomain {
if ((self = [super init])) {
_networkID = [networkID copy];
_displayName = [displayName copy];
_userDomain = [userDomain copy];
_loggedIn = YES;
}
return self;
}
#end
And I will create a new one with code like this:
UserInfo *myUserInfo = [[UserInfo alloc]
initWithUserNetworkID:[loginDictionary objectForKey:#"NetworkID"]
displayName:[loginDictionary objectForKey:#"DisplayName"]
userDomain:[loginDictionary objectForKey:#"UserDomain"]];
I would like to send the message from HelloWorldLayer, and receive it in ScoreLayer, in order to update the label. The CCLOG(#"///addNewScore"); works fine, but then updateScore, in ScoreLayer, does not receive the call, would you know why? Here's my code : (edit: i tried with "retain" in #property, but nothing changes) :
#interface HelloWorldLayer : CCLayer
{
//...
id<ScoreDelegate>delegate;
}
#property (nonatomic,retain) id <ScoreDelegate> delegate;
#implementation HelloWorldLayer
#synthesize delegate;
//...
-(void)addNewScore:(int)num{
CCLOG(#"///addNewScore");//works fine
[delegate updateScore:num];
}
#import <Foundation/Foundation.h>
#protocol ScoreDelegate
-(void)updateScore:(int)num;
#end
#interface ScoreLayer : CCLayer <ScoreDelegate>{
//...
}
-(void)updateScore:(int)num{
CCLOG(#"hello");//DOES NOT WORK
}
#end
Thanks a lot
I suspect that the ScoreLayer is being released before your call. I'm not too familiar with assign, I have only written ARC Objective-C; but I think it is roughly the same as weak (as it should be for delegates). This means that in order for that pointer to be valid, someone else in the application needs to "own" the ScoreLayer.
Now, that being said, I've only assumed that you are properly connecting the two objects in the first place. There isn't code posted which shows that, but this matter of a possibly-released ScoreLayer is important enough to keep in mind either way.
You would declare that protocol (delegate method) in the interface file of HelloWorldLayer. You would then put the delegate method inside ScoreLayer.m:
-(void)updateScore:(int)num {
// Do something
}
The way it is now, you declared the protocol in the wrong class.
I've searched for the answer to this question, and the answers I'm finding don't work.
I have a view that is a subclass of UIView to which I've added a property. I would like to access this property from the subviews created by this view. Is that possible?
I've tried referring to self.superview.propertyname but I get an error that propertyname is not found on object of type UIView. Well, right. I realize that since it's a subclass of UIView, it's a UIView, but how can I get it to know about the extra property I added?
You have a number of options, two of them are:
1. Casting:
#implementation SubviewView
- (void)blah
{
((CustomView *)self.superview).property = ...`
}
#end
2. Delegates:
#protocol SubviewViewDelegate
- (void)customView:(SubView *)sv modified:(...)value;
#end
#class SubView
#property (nonatomic, weak) id <CustomViewDelegate> delegate;
#end
#implementation SubviewView
- (void)blah
{
[self.delegate subView modified:...];
}
#end
#implementation CustomView
- (void)subView:(SubView *)sv modified:(...)value
{
self.property = value;
}
#end
Although the second option is more code, I think it is often better suited. Using delegates reduces coupling and works nicely with the Law of Demeter. For more info see this documentation.