Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

objective-C how to declare private property for category?

I'm new to objective-C, so apologies if this is repeated somewhere. I have a category(?) that is something like:

inside SomeClass.h:

@interface SomeClass (SomeCategory) <SomeDelegate>
@property (nonatomic, retain) id somePublicProperty;
@property (nonatomic, retain) id someProperty; // <-- i want to move this to "private"
@end

and now in my SomeClass.m, all i have is:

@implementation SomeClass (SomeCategory)

// dynamic setters/getters here for someProperty.

@end

I think the someProperty is public. how do i make this "private"? (in other words, how do i syntactically put this in the .m file? i tried to use

@interface SomeClass (SomeCategory) {
    @property (nonatomic, retain) somePrivateProperty;
} 
@end

but it just complains that i have duplicate definition of the category. how do i do this correctly?

like image 417
David T. Avatar asked Aug 25 '14 20:08

David T.


People also ask

What is a category Objective-C?

A category allows you to add methods to an existing class—even to one for which you do not have the source. Categories are a powerful feature that allows you to extend the functionality of existing classes without subclassing. Check the apple doc for the Category in Objective-C.

What is Property in Obj C?

Properties in Objective-C allow you to provide a well-defined interface for other classes to manipulate (i.e. get or set) attributes of a class. They also insulate external classes from the implementation details of the attributes (this separation of function and implementation is known as encapsulation).


2 Answers

In your .h file, you should not give the category. Just use:

@interface SomeClass : SomeBaseClass < SomeDelegate>
    @property (nonatomic, retain) id somePublicProperty;
@end

In your .m file, define your private property inside a class extension:

@interface SomeClass ()
    @property (nonatomic, retain) id somePrivateProperty;
@end

A class extension is not a like category in that it allows you to extend an interface as well as add new storage to your class.

In a class category, you can define new properties, but no storage will be allocated for it, so you have to do it by hand:

@interface SomeClass (SomeBaseCategory)
    @property (nonatomic, retain) id somePrivateProperty;
@end

@implementation SomeClass {
    id _somePrivateProperty;
}

    - (void)setSomePrivateProperty:(id)property {

        _somePrivateProperty = property;
    }

    - (id)somePrivateProperty {
         return _somePrivateProperty;
    }

@end

Otherwise your app will crash.

In any case, keep in mind that given the dynamic nature of Objective-C, your property will never be fully private, since you can always send a message to an Objective-C object through objc_msgsend and thus set or read the property value.

EDIT:

If you do not have the source code for a class implementation, you cannot define a class extension (as per source linked above).

In this case, you could use object association to define properties.

like image 60
sergio Avatar answered Oct 21 '22 11:10

sergio


Just add the category definition in the .m file OUTSIDE the implementation block

Like so:

@interface MyClass (MyCategory)
@property (assign) BOOL myPrivateProperty;
@end

@implementation MyClass
...
@end
like image 29
Daniel Shteremberg Avatar answered Oct 21 '22 10:10

Daniel Shteremberg