Mark property as deprecated in Objective C - objective-c

How can I mark a #property in Objective C as deprecated?

Unless you really want to deprecate based on iOS version, which I suspect you don't want to do, you can use DEPRECATED_ATTRIBUTE
#property (strong) NSObject *object DEPRECATED_ATTRIBUTE;

from NSObjCRuntime.h
#define NS_AVAILABLE(_mac, _ios)
#define NS_AVAILABLE_MAC(_mac)
#define NS_AVAILABLE_IOS(_ios)
#define NS_DEPRECATED(_macIntro, _macDep, _iosIntro, _iosDep)
#define NS_DEPRECATED_MAC(_macIntro, _macDep)
#define NS_DEPRECATED_IOS(_iosIntro, _iosDep)
you can use these macros
this is one example in UITableViewCell.h
#property(nonatomic,copy) NSString *text NS_DEPRECATED_IOS(2_0, 3_0); // default is nil

You can also use DEPRECATED_MSG_ATTRIBUTE("Use anotherProperty instead.") and provide a meaningful message hinting the user what to use in place of the deprecated property.
Xcode will show a warning when the property is used.
example:
#property (nonatomic) NSString *someProperty DEPRECATED_MSG_ATTRIBUTE("Use anotherProperty instead.");

you can type macro like this below one in .pch to be gloabl for all the app
#define DEPRECATED_ATTRIBUTE __attribute__((deprecated))
in mark the method as following example
-(void) exmapleMethodName DEPRECATED_ATTRIBUTE{
// code
}

Related

why do other properties need nullability type specifier

I am getting the date when a photo was created using
#property(nonatomic, readonly, nullable) AVMetadataItem *creationDate;
in my .h file. Then I get the value of the AVMetadataItem of my video asset.
This works fine however when I add this to my .h file all the rest of my properties get a warning that they are missing a nullability type specifier, even though they don't need it when I don't have this property listed. How do I do this without having to add a nullablity specifier to every other property etc. in the .h file?
Once you add a nullability annotation, ObjC expects that you have audited the file. To mark regions of the file to be nonull by default, use the NS_ASSUME_NONNULL_BEGIN and NS_ASSUME_NONNULL_END macros.
From the Nullability and Objective-C blog post:
NS_ASSUME_NONNULL_BEGIN
#interface AAPLList : NSObject <NSCoding, NSCopying>
// ...
- (nullable AAPLListItem *)itemWithName:(NSString *)name;
- (NSInteger)indexOfItem:(AAPLListItem *)item;
#property (copy, nullable) NSString *name;
#property (copy, readonly) NSArray *allItems;
// ...
#end
NS_ASSUME_NONNULL_END
// --------------
self.list.name = nil; // okay
AAPLListItem *matchingItem = [self.list itemWithName:nil]; // warning!
This will replace all the ! types in your Swift bridging with explicit non-optional types. You should audit the code to make sure this is correct. But for the common case, where most things are nonnull, the macros greatly simplify adoption.

Hide an Objective-C initializer (or method) from Swift

I have a Framework with has one Objective-C class with one designated initializer which takes two NSArrays. Inside the Framework, I have defined a Swift extension which provides an extra initializer which takes an array of tuples instead of the two arrays.
When importing the Framework eternally, is it possible to hide the original Objective-C initializer from Swift (so only the initializer taking the array of tuples can be used) but keep it available when using the Framework from Objective-C code?
Answer by #mattt:
Use the NS_SWIFT_UNAVAILABLE macro (available only on Xcode 7 and up).
You could:
YourApp-Brindging-Header.h
#define __BRIDGING__
#import "YourObjCObject.h"
#undef __BRIDGING__
YourObjCObject.h
#import <Foundation/Foundation.h>
#interface YourObjCObject : NSObject
#property (assign, nonatomic) NSInteger count;
- (instancetype)initWithArray:(NSArray *)ary1 Array2:(NSArray *)ary2 NS_DESIGNATED_INITIALIZER
#ifdef __BRIDGING__
NS_UNAVAILABLE
#endif
;
#end

Use and Access Global/Extern Variables in Objective C

I know this question has been asked a billion times, but my particular question hasn't been answered. So sorry about the repetitiveness.
So I know how to declare and define extern variables (correct me if I'm wrong):
in foo.h file:
extern NSString *foo;
in foo.m file:
NSString *foo = #"fooey";
But then say I want to access/change the variable in the hoo.m file. How would I do that?
In .h
#interface SOViewController : UIViewController{
NSString * variable;
}
in .m you can set it wherever.
For example, viewDidLoad.
You can also declare this in the .m file by putting the declaration
#interface SOViewController(){
NSString * variable;
}
// #property (strong, nonatomic) NSString * myString; might be appropriate here instead
#end
Before the #implementation.
Ideally, since this is object-oriented programming, though, best practice would be to make the string a property of the class.
If you are really set on the extern keyword here is a stackoverflow post on how to use it Objective C - How to use extern variables?
EDIT
The question came down to how to pass variables around. You can look at this article How to pass prepareForSegue: an object to see an example of how to do that with seguing.

How to make debug code using #ifdef directive. Objective-c

i want to make a question about developing using #ifdef directive.
I want do make some code in objective-c only for debug use, for example:
in main function do this:
#define DEBUG_LEVEL
in my interface do this:
#ifdef DEBUG_LEVEL
BOOL editorIsDragged;
BOOL editorIsSelected;
#endif
.... other property
#ifdef #DEBUG_LEVEL
#property (nonatomic, readwrite) BOOL editorIsDragged;
#property (nonatomic, readwrite) BOOL editorIsSelected;
#endif
then in my implementation do this:
#ifdef #DEBUG_LEVEL
#synthetize editorIsDragged, editorIsSelected;
#endif
but i receve an error because in synthetize editorIsDragged and editorIsSelected are not defined.
If i try to define my own setter/getter method I receive the same error, because my vars (editorIsDragged and editorIsSelected) does not exist for XCode!
I in C use this method for write only debug code, but in obj-c what i must use??
thank you!
Shouldn't you put your #define DEBUG_LEVEL in a header file that gets included in all places that needs to know it? Like setting in in the build settings or putting in the *.pch. And I'm not sure if that a typo but you have also #define #DEBUG_LEVEL (see the second hash?) in the code here.

How to store blocks in properties in Objective-C?

I'd like to store objective-c block in a property for later use. I wasn't sure how to do it so I googled a bit and there is very little info about the subject. But I've managed to find the solution eventually and I've thought that it might be worth sharing for other newbies like me.
Initially I've thought that I would need to write the properties by hand to use Block_copy & Block_release.
Fortunately I've found out that blocks are NSObjects and - copy/- release is equivalent to Block_copy/Block_release. So I can use #property (copy) to auto generate setters & getters.
Edit: updated for ARC
typedef void(^MyCustomBlock)(void);
#interface MyClass : NSObject
#property (nonatomic, copy) MyCustomBlock customBlock;
#end
#implementation MyClass
#end
MyClass * c = [[MyClass alloc] init];
c.customBlock = ^{
NSLog(#"hello.....");
}
c.customBlock();
Alternatively, without the typedef
#property (copy, nonatomic) void (^selectionHandler) (NSDictionary*) ;
You can find a very good explanation of this in WWDC 2012 session 712 starting in page 83. The correct way of saving a block under ARC is the following:
#property(strong) my_block_type work;
Be careful with the retain cycles. A good way to solve is set the block to nil when you do not need it anymore:
self.work = nil;