I have been trying to set an Integer value from one class to another like below, but i can't do this.
#interface ClassA : UIViewController {
}
#property(nonatomic, assign) int m_selrow;
+ (void)setRowSelected : (int)selecetedRow;
#end
#implementation ClassA
+ (void)setRowSelected : (int)selecetedRow {
m_selrow = selecetedRow;
}
#end
//Accessing from different Class,
//Class B implementation:
[ClassA setRowSelected:indexPath.row];
Problem is, it says "m_selrow is use of undeclared identifier from setRowSelected() method. How to properly use the variable and set it from another class.
Interface should inherit from something, I changed it to NSObject
I also added static declartion to of member field to class A
After fixing those, it works smoothly.
Here are my changes:
#interface ClassA : NSObject{
}
#property(nonatomic, assign) int m_selrow;
+ (void)setRowSelected : (int)selecetedRow;
#end
#implementation ClassA
static int m_selrow;
+ (void)setRowSelected : (int)selecetedRow {
m_selrow = selecetedRow;
NSLog(#"============= > %d", m_selrow);
}
#end
[ClassA setRowSelected: 1];
Related
I have a class MyClass subclassed from NSObject. It is written in Objective-C. It has a property with custom getter and setter:
#interface MyClass : NSObject
#property (getter = getIsBypassEnabled, setter = setIsBypassEnabled:) BOOL isBypassEnabled;
#end
And both of these functions are defined in implementation:
#implementation MyClass
// Initializer and other stuff
// ...
- (void) setIsBypassEnabled: (BOOL) newValue
{
_value = newValue;
}
- (BOOL) getIsBypassEnabled
{
return _value;
}
#end
But when I try to set the property from Swift like:
let objcClass = MyClass()
objcClass.isBypassEnabled = true
I get an error 'isBypassEnabled' has been renamed to 'getIsBypassEnabled'. But I need to set the value, not get it!
Trying
objcClass.setIsBypassEnabled(true)
gives me an error that my class has no such member.
Declaring
- (BOOL) getIsBypassEnabled;
- (void) setIsBypassEnabled: (BOOL) newValue;
explicitly in .h file does not help either.
How do I resolve the issue? Thank you.
#interface MyClass : NSObject
#property (getter = getIsBypassEnabled, setter = setIsBypassEnabled:) BOOL isBypassEnabled;
#end
is mapped to Swift as
open class MyClass : NSObject {
open var getIsBypassEnabled: Bool
}
so you can set the property actually with
let objcClass = MyClass()
objcClass.getIsBypassEnabled = true
I don't know if this mapping is intended or not, you might want to
file a bug report.
You can also override the Swift mapping with
#interface MyClass : NSObject
#property (getter = getIsBypassEnabled, setter = setIsBypassEnabled:) BOOL isBypassEnabled
NS_SWIFT_NAME(isBypassEnabled);
#end
and then
let objcClass = MyClass()
objcClass.isBypassEnabled = true
works as intended.
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
I have a function , return a protocol.
But Xcode waring:
[Returning 'HpadMoblieCollectorBooleanResult *'__strong from a function with incompatible result type 'id' ]
-----------sep line ---------------------
Question detail :
HpadCollectorBooleanResult.h
#protocol HpadCollectorBooleanResult <NSObject>
- (void) result:(void(^)(BOOL))block ;
#end
I have a Class to implement HpadCollectorBooleanResult protocol ,
the Class is HpadMoblieCollector .
HpadMoblieCollector.h
#import "HpadCollectorResult.h"
#interface HpadMoblieCollector : NSObject
// clear All
- (id<HpadCollectorBooleanResult>) favorite_ajax_clear ;
#end
and the .m file is
HpadMoblieCollector.m
#interface HpadMoblieCollectorBooleanResult<HpadCollectorBooleanResult> : NSObject
{
void(^_result)(BOOL) ;
BOOL isExe ;
BOOL resultFlag ;
}
#end
#implementation HpadMoblieCollector
// 清空手机收藏夹
- (id<HpadCollectorBooleanResult>) favorite_ajax_clear
{
HpadMoblieCollectorBooleanResult *result = [[HpadMoblieCollectorBooleanResult alloc] init] ;
return result ;
// Xcode waring:
// Returning 'HpadMoblieCollectorBooleanResult *'__strong from a function
// with incompatible result type 'id<HpadCollectorBooleanResult>'
}
#end
You can see , the method "- (id< HpadCollectorBooleanResult >) favorite_ajax_clear" have an error ,
I cannot solve the problem .
1、Can you tell me why the Xcode send a warning message ?
2、Can you help me to resolve it ?
Why #interface HpadMoblieCollectorBooleanResult<HpadCollectorBooleanResult> : NSObject?
Change it to #interface HpadMoblieCollectorBooleanResult : NSObject<HpadCollectorBooleanResult> and the warning should go away.
id<HpadCollectorBooleanResult> means an object (id) that implements the protocol HpadCollectorBooleanResult.
You are creating an instance of the class HpadMoblieCollectorBooleanResult with alloc [init]].
If HpadMoblieCollectorBooleanResult is a class you need to change the return type of your method to - (HpadMoblieCollectorBooleanResult *) favorite_ajax_clear
If HpadMoblieCollectorBooleanResult is a protocol you need to create a new class that implements that protocol. Then you can return an instance of that class. In this case it's a protocol.
#interface MyClass : NSObject <HpadCollectorBooleanResult>
- (void) result:(void(^)(BOOL))block
{
}
#end
I have two classes: classA and ClassB, now I have included Class B into Class A
So inside classA is written#import "classB.h"
Now, my question is how would you set a variable inside classA FROM A METHOD INSIDE classB, such that suppose A is an instance of classA, and B is an instance of classB and I say A.var = self.var in the method, suppose var are properties in both classes.
When instantiating ClassB you can set the var from ClassA
ClassB *b = [[ClassB alloc]init];
b.var = self.var;
so from ClassB you can access the values like below
NSLog("%#",self.var)
You can either send a variable by reference to the method of B class or you can return an object from the function in classB and assign it to a variable in classA:
self.var=[classB func];
if func is a static function in class classB
or
self.var=[B func];
if func is a non-static function in class classB and B is an object of classB in classA
You can either make the variable public, or make it into a property. For example, to make it public:
#interface ClassA
{
#public
int var;
}
// methods...
#end
// Inside a ClassB method:
ClassA *obj = ...;
obj->var = 3;
To make it a property:
#interface ClassA
{
int var; // # this is protected by default
}
#property (readwrite, nonatomic) int var;
// methods...
#end
#implementation ClassA
#synthesize var;
...
#end
// In ClassB
ClassA *obj = ...;
obj.var = 3; // implicitly calls [obj setVar:3]
int x = obj.var; // implicitly calls x = [obj var];
Newbie to objective C...
NOTE: This is a conceptual problem, as I'm trying to translate "public and private" from what I know about other languages.
How can I access the "stringB" ivar through the "public" method?
myClass.h
#interface myClass : UIViewController {
}
#property (nonatomic, retain) NSString *stringA;
#property (nonatomic, retain) NSString *stringB;
- (void)dealWithStringA;
+ (void)dealWithStringB;
myClass.m
#import "myClass.h"
#interface myClass () {
}
#end
#implementation myClass
// My "private" function
- (void)dealWithStringA
{
return _stringA;
}
// My "public" function
+ (void)dealWithStringB
{
// Errors with: Instance variable "stringB" accessed in class method
return _stringB;
}
The method starting with a + is called a class method in objective C where a method starting with - is an instance method. An instance method can be performed on an instance of that class only.
Also the return type for your method would be an NSString since you are expecting to get a string object from that method.
For a class method, you'll need to create an autoreleasing instance of that class and then perform operations on that instance.
For eg.
+ (NSString*)dealWithStringB
{
MyClass *myClass = [[[MyClass alloc] init] autorelease];
myClass.stringB = #"Its String B";//It's an absurd example
return myClass.stringB;
}
You are wrong with understanding "+", "-" - it's not about private / public.
To have a private function you should implement that in your .m file:
#interface YourClass ()
- (id) privateMethod;
#end
Everything you declare in .h file will be public:
#interface YourClass : NSObject
- (id)someMethod //public
#end
"+" is used for static functions so you can call them without having an instance of a class.
For example in your case:
[myClass dealWithStringB];
and for "-" function you need instance.
[[[myClass alloc] init] dealWithStringA];
The static functions can be used when you don't need any properties from a class or to they are pretty often used to create instances of classes.
The "+" prefix means class method, not public. A "-" stands for instance method, not private.
Both public and private methods can access the private state of the class or instance.
myClass.h (Similar to yours)
#interface myClass : UIViewController
{
}
#property (nonatomic, retain) NSString *stringA;
#property (nonatomic, retain) NSString *stringB;
- (void)dealWithStringA;
+ (void)dealWithStringB;
#end
myClass.m
#implementation myClass
#synthesize stringA ;
#synthesize stringB ;
static myClass* instance = nil;
+(void) dealWithStringB
{
if(instance==nil)
{
instance=[myClass alloc]init];
}
else
{
//Access the field this way
printf("#"The string content is %#",instance.stringB);
}
}
Hope its Clear!!!